react-hook-form 7.0.0-rc.8 → 7.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -26,7 +26,7 @@ function _interopNamespace(e) {
26
26
 
27
27
  var React__namespace = /*#__PURE__*/_interopNamespace(React);
28
28
 
29
- var isUndefined = (val) => val === undefined;
29
+ var isCheckBoxInput = (element) => element.type === 'checkbox';
30
30
 
31
31
  var isNullOrUndefined = (value) => value == null;
32
32
 
@@ -36,8 +36,20 @@ var isObject = (value) => !isNullOrUndefined(value) &&
36
36
  isObjectType(value) &&
37
37
  !(value instanceof Date);
38
38
 
39
+ var getControllerValue = (event) => isObject(event) && event.target
40
+ ? isCheckBoxInput(event.target)
41
+ ? event.target.checked
42
+ : event.target.value
43
+ : event;
44
+
45
+ var getNodeParentName = (name) => name.substring(0, name.search(/.\d/)) || name;
46
+
47
+ var isNameInFieldArray = (names, name) => [...names].some((current) => getNodeParentName(name) === current);
48
+
39
49
  var compact = (value) => value.filter(Boolean);
40
50
 
51
+ var isUndefined = (val) => val === undefined;
52
+
41
53
  var get = (obj = {}, path, defaultValue) => {
42
54
  const result = compact(path.split(/[,[\].]+?/)).reduce((result, key) => (isNullOrUndefined(result) ? result : result[key]), obj);
43
55
  return isUndefined(result) || result === obj
@@ -47,6 +59,175 @@ var get = (obj = {}, path, defaultValue) => {
47
59
  : result;
48
60
  };
49
61
 
62
+ const EVENTS = {
63
+ BLUR: 'blur',
64
+ CHANGE: 'change',
65
+ };
66
+ const VALIDATION_MODE = {
67
+ onBlur: 'onBlur',
68
+ onChange: 'onChange',
69
+ onSubmit: 'onSubmit',
70
+ onTouched: 'onTouched',
71
+ all: 'all',
72
+ };
73
+ const SELECT = 'select';
74
+ const UNDEFINED = 'undefined';
75
+ const INPUT_VALIDATION_RULES = {
76
+ max: 'max',
77
+ min: 'min',
78
+ maxLength: 'maxLength',
79
+ minLength: 'minLength',
80
+ pattern: 'pattern',
81
+ required: 'required',
82
+ validate: 'validate',
83
+ };
84
+
85
+ var omit = (source, key) => {
86
+ const copy = Object.assign({}, source);
87
+ delete copy[key];
88
+ return copy;
89
+ };
90
+
91
+ const FormContext = React__namespace.createContext(null);
92
+ FormContext.displayName = 'RHFContext';
93
+ const useFormContext = () => React__namespace.useContext(FormContext);
94
+ const FormProvider = (props) => (React__namespace.createElement(FormContext.Provider, { value: omit(props, 'children') }, props.children));
95
+
96
+ var getProxyFormState = (isProxyEnabled, formState, readFormStateRef, localReadFormStateRef, isRoot = true) => isProxyEnabled
97
+ ? new Proxy(formState, {
98
+ get: (obj, prop) => {
99
+ if (prop in obj) {
100
+ if (readFormStateRef.current[prop] !== VALIDATION_MODE.all) {
101
+ readFormStateRef.current[prop] = isRoot
102
+ ? VALIDATION_MODE.all
103
+ : true;
104
+ }
105
+ localReadFormStateRef &&
106
+ (localReadFormStateRef.current[prop] = true);
107
+ return obj[prop];
108
+ }
109
+ return undefined;
110
+ },
111
+ })
112
+ : formState;
113
+
114
+ var isEmptyObject = (value) => isObject(value) && !Object.keys(value).length;
115
+
116
+ var shouldRenderFormState = (formState, readFormStateRef, isRoot) => isEmptyObject(formState) ||
117
+ Object.keys(formState).length >= Object.keys(readFormStateRef).length ||
118
+ Object.keys(formState).find((key) => readFormStateRef[key] ===
119
+ (isRoot ? VALIDATION_MODE.all : true));
120
+
121
+ var isWeb = typeof window !== UNDEFINED &&
122
+ typeof window.HTMLElement !== UNDEFINED &&
123
+ typeof document !== UNDEFINED;
124
+
125
+ const isProxyEnabled = isWeb ? 'Proxy' in window : typeof Proxy !== UNDEFINED;
126
+
127
+ function useFormState(props) {
128
+ const methods = useFormContext();
129
+ const { formStateRef, formStateSubjectRef, readFormStateRef } = (props && props.control) || methods.control;
130
+ const [formState, updateFormState] = React__namespace.useState(formStateRef.current);
131
+ const readFormState = React__namespace.useRef({
132
+ isDirty: false,
133
+ dirtyFields: false,
134
+ touchedFields: false,
135
+ isValidating: false,
136
+ isValid: false,
137
+ errors: false,
138
+ });
139
+ React__namespace.useEffect(() => {
140
+ const formStateSubscription = formStateSubjectRef.current.subscribe({
141
+ next: (formState) => {
142
+ shouldRenderFormState(formState, readFormState.current) &&
143
+ updateFormState(Object.assign(Object.assign({}, formStateRef.current), formState));
144
+ },
145
+ });
146
+ return () => formStateSubscription.unsubscribe();
147
+ }, []);
148
+ return getProxyFormState(isProxyEnabled, formState, readFormStateRef, readFormState, false);
149
+ }
150
+
151
+ function useController({ name, rules, defaultValue, control, }) {
152
+ const methods = useFormContext();
153
+ const { defaultValuesRef, register, fieldsRef, fieldArrayNamesRef, controllerSubjectRef, } = control || methods.control;
154
+ const { onChange, onBlur, ref } = register(name, rules);
155
+ const [value, setInputStateValue] = React__namespace.useState(isUndefined(get(fieldsRef.current, name)._f.value) ||
156
+ isNameInFieldArray(fieldArrayNamesRef.current, name)
157
+ ? isUndefined(defaultValue)
158
+ ? get(defaultValuesRef.current, name)
159
+ : defaultValue
160
+ : get(fieldsRef.current, name)._f.value);
161
+ const formState = useFormState({
162
+ control: control || methods.control,
163
+ });
164
+ get(fieldsRef.current, name)._f.value = value;
165
+ React__namespace.useEffect(() => {
166
+ const controllerSubscription = controllerSubjectRef.current.subscribe({
167
+ next: (data) => (!data.name || name === data.name) &&
168
+ setInputStateValue(get(data.values, name)),
169
+ });
170
+ ref({
171
+ target: value,
172
+ });
173
+ return () => controllerSubscription.unsubscribe();
174
+ }, [name]);
175
+ return {
176
+ field: {
177
+ onChange: (event) => {
178
+ const value = getControllerValue(event);
179
+ setInputStateValue(value);
180
+ onChange({
181
+ target: {
182
+ value,
183
+ name: name,
184
+ },
185
+ type: EVENTS.CHANGE,
186
+ });
187
+ },
188
+ onBlur: () => {
189
+ onBlur({
190
+ target: {
191
+ name: name,
192
+ },
193
+ type: EVENTS.BLUR,
194
+ });
195
+ },
196
+ name,
197
+ value,
198
+ ref,
199
+ },
200
+ formState,
201
+ fieldState: Object.defineProperties({}, {
202
+ invalid: {
203
+ get() {
204
+ return !!get(formState.errors, name);
205
+ },
206
+ },
207
+ isDirty: {
208
+ get() {
209
+ return !!get(formState.dirtyFields, name);
210
+ },
211
+ },
212
+ isTouched: {
213
+ get() {
214
+ return !!get(formState.touchedFields, name);
215
+ },
216
+ },
217
+ error: {
218
+ get() {
219
+ return get(formState.errors, name);
220
+ },
221
+ },
222
+ }),
223
+ };
224
+ }
225
+
226
+ const Controller = (props) => props.render(useController(props));
227
+
228
+ var appendErrors = (name, validateAllFieldCriteria, errors, type, message) => validateAllFieldCriteria
229
+ ? Object.assign(Object.assign({}, errors[name]), { types: Object.assign(Object.assign({}, (errors[name] && errors[name].types ? errors[name].types : {})), { [type]: message || true }) }) : {};
230
+
50
231
  var isKey = (value) => /^\w*$/.test(value);
51
232
 
52
233
  var stringToPath = (input) => compact(input.replace(/["|']|\]/g, '').split(/\.|\[/));
@@ -74,12 +255,6 @@ function set(object, path, value) {
74
255
  return object;
75
256
  }
76
257
 
77
- var omit = (source, key) => {
78
- const copy = Object.assign({}, source);
79
- delete copy[key];
80
- return copy;
81
- };
82
-
83
258
  const focusFieldBy = (fields, callback, fieldsNames) => {
84
259
  for (const key of fieldsNames || Object.keys(fields)) {
85
260
  const field = get(fields, key);
@@ -102,26 +277,40 @@ const focusFieldBy = (fields, callback, fieldsNames) => {
102
277
  }
103
278
  };
104
279
 
105
- var isPrimitive = (value) => isNullOrUndefined(value) || !isObjectType(value);
106
-
107
- function deepMerge(target, source) {
108
- if (isPrimitive(target) || isPrimitive(source)) {
109
- return source;
110
- }
111
- for (const key in source) {
112
- const targetValue = target[key];
113
- const sourceValue = source[key];
114
- try {
115
- target[key] =
116
- (isObject(targetValue) && isObject(sourceValue)) ||
117
- (Array.isArray(targetValue) && Array.isArray(sourceValue))
118
- ? deepMerge(targetValue, sourceValue)
119
- : sourceValue;
280
+ const getFieldsValues = (fieldsRef, defaultValuesRef = { current: {} }, output = {}) => {
281
+ for (const name in fieldsRef.current) {
282
+ const field = fieldsRef.current[name];
283
+ if (field) {
284
+ const _f = field._f;
285
+ const current = omit(field, '_f');
286
+ set(output, name, _f
287
+ ? _f.ref.disabled || (_f.refs && _f.refs.every((ref) => ref.disabled))
288
+ ? undefined
289
+ : _f.value
290
+ : Array.isArray(field)
291
+ ? []
292
+ : {});
293
+ if (current) {
294
+ getFieldsValues({
295
+ current,
296
+ }, defaultValuesRef, output[name]);
297
+ }
120
298
  }
121
- catch (_a) { }
122
299
  }
123
- return target;
124
- }
300
+ return Object.assign(Object.assign({}, defaultValuesRef.current), output);
301
+ };
302
+
303
+ var generateId = () => {
304
+ const d = typeof performance === UNDEFINED ? Date.now() : performance.now() * 1000;
305
+ return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {
306
+ const r = (Math.random() * 16 + d) % 16 | 0;
307
+ return (c == 'x' ? r : (r & 0x3) | 0x8).toString(16);
308
+ });
309
+ };
310
+
311
+ var mapIds = (values = [], keyName) => values.map((value) => (Object.assign({ [keyName]: (value && value[keyName]) || generateId() }, value)));
312
+
313
+ var isPrimitive = (value) => isNullOrUndefined(value) || !isObjectType(value);
125
314
 
126
315
  function deepEqual(object1, object2, isErrorObject) {
127
316
  if (isPrimitive(object1) ||
@@ -152,6 +341,25 @@ function deepEqual(object1, object2, isErrorObject) {
152
341
  return true;
153
342
  }
154
343
 
344
+ function deepMerge(target, source) {
345
+ if (isPrimitive(target) || isPrimitive(source)) {
346
+ return source;
347
+ }
348
+ for (const key in source) {
349
+ const targetValue = target[key];
350
+ const sourceValue = source[key];
351
+ try {
352
+ target[key] =
353
+ (isObject(targetValue) && isObject(sourceValue)) ||
354
+ (Array.isArray(targetValue) && Array.isArray(sourceValue))
355
+ ? deepMerge(targetValue, sourceValue)
356
+ : sourceValue;
357
+ }
358
+ catch (_a) { }
359
+ }
360
+ return target;
361
+ }
362
+
155
363
  function setDirtyFields(values, defaultValues, dirtyFields, parentNode, parentName) {
156
364
  let index = -1;
157
365
  while (++index < values.length) {
@@ -175,476 +383,625 @@ function setDirtyFields(values, defaultValues, dirtyFields, parentNode, parentNa
175
383
  }
176
384
  var setFieldArrayDirtyFields = (values, defaultValues, dirtyFields) => deepMerge(setDirtyFields(values, defaultValues, dirtyFields.slice(0, values.length)), setDirtyFields(defaultValues, values, dirtyFields.slice(0, values.length)));
177
385
 
178
- var isEmptyObject = (value) => isObject(value) && !Object.keys(value).length;
179
-
180
- const EVENTS = {
181
- BLUR: 'blur',
182
- CHANGE: 'change',
183
- };
184
- const VALIDATION_MODE = {
185
- onBlur: 'onBlur',
186
- onChange: 'onChange',
187
- onSubmit: 'onSubmit',
188
- onTouched: 'onTouched',
189
- all: 'all',
190
- };
191
- const SELECT = 'select';
192
- const UNDEFINED = 'undefined';
193
- const INPUT_VALIDATION_RULES = {
194
- max: 'max',
195
- min: 'min',
196
- maxLength: 'maxLength',
197
- minLength: 'minLength',
198
- pattern: 'pattern',
199
- required: 'required',
200
- validate: 'validate',
201
- };
202
-
203
- var shouldRenderFormState = (formState, readFormStateRef, isRoot) => isEmptyObject(formState) ||
204
- Object.keys(formState).length >= Object.keys(readFormStateRef).length ||
205
- Object.keys(formState).find((key) => readFormStateRef[key] ===
206
- (isRoot ? VALIDATION_MODE.all : true));
207
-
208
- const getFieldsValues = (fieldsRef, defaultValuesRef = { current: {} }, output = {}) => {
209
- for (const name in fieldsRef.current) {
210
- const field = fieldsRef.current[name];
211
- if (field) {
212
- const _f = field._f;
213
- const current = omit(field, '_f');
214
- set(output, name, _f
215
- ? _f.ref.disabled || (_f.refs && _f.refs.every((ref) => ref.disabled))
216
- ? undefined
217
- : _f.value
218
- : Array.isArray(field)
219
- ? []
220
- : {});
221
- if (current) {
222
- getFieldsValues({
223
- current,
224
- }, defaultValuesRef, output[name]);
225
- }
226
- }
227
- }
228
- return Object.assign(Object.assign({}, defaultValuesRef.current), output);
229
- };
230
-
231
- const defaultReturn = {
232
- isValid: false,
233
- value: null,
234
- };
235
- var getRadioValue = (options) => Array.isArray(options)
236
- ? options.reduce((previous, option) => option && option.checked && !option.disabled
237
- ? {
238
- isValid: true,
239
- value: option.value,
240
- }
241
- : previous, defaultReturn)
242
- : defaultReturn;
243
-
244
- var getMultipleSelectValue = (options) => [...options]
245
- .filter(({ selected }) => selected)
246
- .map(({ value }) => value);
247
-
248
- var isRadioInput = (element) => element.type === 'radio';
249
-
250
- var isFileInput = (element) => element.type === 'file';
386
+ function append(data, value) {
387
+ return [...data, ...(Array.isArray(value) ? value : [value])];
388
+ }
251
389
 
252
- var isCheckBoxInput = (element) => element.type === 'checkbox';
390
+ var fillEmptyArray = (value) => Array.isArray(value) ? Array(value.length).fill(undefined) : undefined;
253
391
 
254
- var isMultipleSelect = (element) => element.type === `${SELECT}-multiple`;
392
+ function insert(data, index, value) {
393
+ return [
394
+ ...data.slice(0, index),
395
+ ...(Array.isArray(value) ? value : [value]),
396
+ ...data.slice(index),
397
+ ];
398
+ }
255
399
 
256
- const defaultResult = {
257
- value: false,
258
- isValid: false,
259
- };
260
- const validResult = { value: true, isValid: true };
261
- var getCheckboxValue = (options) => {
262
- if (Array.isArray(options)) {
263
- if (options.length > 1) {
264
- const values = options
265
- .filter((option) => option && option.checked && !option.disabled)
266
- .map((option) => option.value);
267
- return { value: values, isValid: !!values.length };
400
+ var moveArrayAt = (data, from, to) => {
401
+ if (Array.isArray(data)) {
402
+ if (isUndefined(data[to])) {
403
+ data[to] = undefined;
268
404
  }
269
- return options[0].checked && !options[0].disabled
270
- ? // @ts-expect-error expected to work in the browser
271
- options[0].attributes && !isUndefined(options[0].attributes.value)
272
- ? isUndefined(options[0].value)
273
- ? validResult
274
- : { value: options[0].value, isValid: true }
275
- : validResult
276
- : defaultResult;
405
+ data.splice(to, 0, data.splice(from, 1)[0]);
406
+ return data;
277
407
  }
278
- return defaultResult;
408
+ return [];
279
409
  };
280
410
 
281
- var getFieldValueAs = (value, { valueAsNumber, valueAsDate, setValueAs }) => valueAsNumber
282
- ? value === ''
283
- ? NaN
284
- : +value
285
- : valueAsDate
286
- ? new Date(value)
287
- : setValueAs
288
- ? setValueAs(value)
289
- : value;
411
+ function prepend(data, value) {
412
+ return [...(Array.isArray(value) ? value : [value]), ...data];
413
+ }
290
414
 
291
- function getFieldValue(field) {
292
- if (field && field._f) {
293
- const ref = field._f.ref;
294
- if (ref.disabled) {
295
- return;
296
- }
297
- if (isFileInput(ref)) {
298
- return ref.files;
299
- }
300
- if (isRadioInput(ref)) {
301
- return getRadioValue(field._f.refs).value;
302
- }
303
- if (isMultipleSelect(ref)) {
304
- return getMultipleSelectValue(ref.options);
305
- }
306
- if (isCheckBoxInput(ref)) {
307
- return getCheckboxValue(field._f.refs).value;
308
- }
309
- return getFieldValueAs(isUndefined(ref.value) ? field._f.ref.value : ref.value, field._f);
415
+ function removeAtIndexes(data, indexes) {
416
+ let i = 0;
417
+ const temp = [...data];
418
+ for (const index of indexes) {
419
+ temp.splice(index - i, 1);
420
+ i++;
310
421
  }
311
- }
422
+ return compact(temp).length ? temp : [];
423
+ }
424
+ var removeArrayAt = (data, index) => isUndefined(index)
425
+ ? []
426
+ : removeAtIndexes(data, (Array.isArray(index) ? index : [index]).sort((a, b) => a - b));
312
427
 
313
- var isErrorStateChanged = ({ errors, name, error, validFields, fieldsWithValidation, }) => {
314
- const isValid = isUndefined(error);
315
- const previousError = get(errors, name);
316
- return ((isValid && !!previousError) ||
317
- (!isValid && !deepEqual(previousError, error, true)) ||
318
- (isValid && get(fieldsWithValidation, name) && !get(validFields, name)));
428
+ var swapArrayAt = (data, indexA, indexB) => {
429
+ data[indexA] = [data[indexB], (data[indexB] = data[indexA])][0];
319
430
  };
320
431
 
321
- var isRegex = (value) => value instanceof RegExp;
322
-
323
- var getValueAndMessage = (validationData) => isObject(validationData) && !isRegex(validationData)
324
- ? validationData
325
- : {
326
- value: validationData,
327
- message: '',
328
- };
329
-
330
- var isString = (value) => typeof value === 'string';
331
-
332
- var isFunction = (value) => typeof value === 'function';
333
-
334
432
  var isBoolean = (value) => typeof value === 'boolean';
335
433
 
336
- var isMessage = (value) => isString(value) || React__namespace.isValidElement(value);
337
-
338
- function getValidateError(result, ref, type = 'validate') {
339
- if (isMessage(result) || (isBoolean(result) && !result)) {
340
- return {
341
- type,
342
- message: isMessage(result) ? result : '',
343
- ref,
344
- };
434
+ function baseGet(object, updatePath) {
435
+ const length = updatePath.slice(0, -1).length;
436
+ let index = 0;
437
+ while (index < length) {
438
+ object = isUndefined(object) ? index++ : object[updatePath[index++]];
345
439
  }
346
- }
347
-
348
- var appendErrors = (name, validateAllFieldCriteria, errors, type, message) => validateAllFieldCriteria
349
- ? Object.assign(Object.assign({}, errors[name]), { types: Object.assign(Object.assign({}, (errors[name] && errors[name].types ? errors[name].types : {})), { [type]: message || true }) }) : {};
350
-
351
- var validateField = async ({ _f: { ref, refs, required, maxLength, minLength, min, max, pattern, validate, name, value: inputValue, }, }, validateAllFieldCriteria) => {
352
- const error = {};
353
- const isRadio = isRadioInput(ref);
354
- const isCheckBox = isCheckBoxInput(ref);
355
- const isRadioOrCheckbox = isRadio || isCheckBox;
356
- const isEmpty = !inputValue || (Array.isArray(inputValue) && !inputValue.length);
357
- const appendErrorsCurry = appendErrors.bind(null, name, validateAllFieldCriteria, error);
358
- const getMinMaxMessage = (exceedMax, maxLengthMessage, minLengthMessage, maxType = INPUT_VALIDATION_RULES.maxLength, minType = INPUT_VALIDATION_RULES.minLength) => {
359
- const message = exceedMax ? maxLengthMessage : minLengthMessage;
360
- error[name] = Object.assign({ type: exceedMax ? maxType : minType, message,
361
- ref }, appendErrorsCurry(exceedMax ? maxType : minType, message));
362
- };
363
- if (required &&
364
- ((!isRadio && !isCheckBox && (isEmpty || isNullOrUndefined(inputValue))) ||
365
- (isBoolean(inputValue) && !inputValue) ||
366
- (isCheckBox && !getCheckboxValue(refs).isValid) ||
367
- (isRadio && !getRadioValue(refs).isValid))) {
368
- const { value, message } = isMessage(required)
369
- ? { value: !!required, message: required }
370
- : getValueAndMessage(required);
371
- if (value) {
372
- error[name] = Object.assign({ type: INPUT_VALIDATION_RULES.required, message, ref: isRadioOrCheckbox ? (refs || [])[0] || {} : ref }, appendErrorsCurry(INPUT_VALIDATION_RULES.required, message));
373
- if (!validateAllFieldCriteria) {
374
- return error;
440
+ return object;
441
+ }
442
+ function unset(object, path) {
443
+ const updatePath = isKey(path) ? [path] : stringToPath(path);
444
+ const childObject = updatePath.length == 1 ? object : baseGet(object, updatePath);
445
+ const key = updatePath[updatePath.length - 1];
446
+ let previousObjRef;
447
+ if (childObject) {
448
+ delete childObject[key];
449
+ }
450
+ for (let k = 0; k < updatePath.slice(0, -1).length; k++) {
451
+ let index = -1;
452
+ let objectRef;
453
+ const currentPaths = updatePath.slice(0, -(k + 1));
454
+ const currentPathsLength = currentPaths.length - 1;
455
+ if (k > 0) {
456
+ previousObjRef = object;
457
+ }
458
+ while (++index < currentPaths.length) {
459
+ const item = currentPaths[index];
460
+ objectRef = objectRef ? objectRef[item] : object[item];
461
+ if (currentPathsLength === index &&
462
+ ((isObject(objectRef) && isEmptyObject(objectRef)) ||
463
+ (Array.isArray(objectRef) &&
464
+ !objectRef.filter((data) => (isObject(data) && !isEmptyObject(data)) || isBoolean(data)).length))) {
465
+ previousObjRef ? delete previousObjRef[item] : delete object[item];
375
466
  }
467
+ previousObjRef = objectRef;
376
468
  }
377
469
  }
378
- if ((!isNullOrUndefined(min) || !isNullOrUndefined(max)) &&
379
- inputValue !== '') {
380
- let exceedMax;
381
- let exceedMin;
382
- const maxOutput = getValueAndMessage(max);
383
- const minOutput = getValueAndMessage(min);
384
- if (!isNaN(inputValue)) {
385
- const valueNumber = ref.valueAsNumber || parseFloat(inputValue);
386
- if (!isNullOrUndefined(maxOutput.value)) {
387
- exceedMax = valueNumber > maxOutput.value;
388
- }
389
- if (!isNullOrUndefined(minOutput.value)) {
390
- exceedMin = valueNumber < minOutput.value;
391
- }
470
+ return object;
471
+ }
472
+
473
+ const useFieldArray = ({ control, name, keyName = 'id', }) => {
474
+ const methods = useFormContext();
475
+ const focusNameRef = React__namespace.useRef('');
476
+ const { isWatchAllRef, watchFieldsRef, getFormIsDirty, watchSubjectRef, fieldArraySubjectRef, fieldArrayNamesRef, fieldsRef, defaultValuesRef, formStateRef, formStateSubjectRef, readFormStateRef, validFieldsRef, fieldsWithValidationRef, fieldArrayDefaultValuesRef, } = control || methods.control;
477
+ const [fields, setFields] = React__namespace.useState(mapIds(get(fieldArrayDefaultValuesRef.current, getNodeParentName(name))
478
+ ? get(fieldArrayDefaultValuesRef.current, name, [])
479
+ : get(defaultValuesRef.current, name, []), keyName));
480
+ set(fieldArrayDefaultValuesRef.current, name, [...fields]);
481
+ fieldArrayNamesRef.current.add(name);
482
+ const omitKey = (fields) => fields.map((field) => omit((field || {}), keyName));
483
+ const getCurrentFieldsValues = () => {
484
+ const values = get(getFieldsValues(fieldsRef, defaultValuesRef), name, []);
485
+ return mapIds(get(fieldArrayDefaultValuesRef.current, name, []).map((item, index) => (Object.assign(Object.assign({}, item), values[index]))), keyName);
486
+ };
487
+ const getFocusDetail = (index, options) => options
488
+ ? !isUndefined(options.focusIndex)
489
+ ? `${name}.${options.focusIndex}`
490
+ : options.focusName
491
+ ? options.focusName
492
+ : !options.shouldFocus
493
+ ? ''
494
+ : `${name}.${index}`
495
+ : `${name}.${index}`;
496
+ const resetFields = (index) => (Array.isArray(index) ? index : [index]).forEach((currentIndex) => set(fieldsRef.current, `${name}${isUndefined(currentIndex) ? '' : `.${currentIndex}`}`, isUndefined(currentIndex) ? [] : undefined));
497
+ const setFieldsAndNotify = (fieldsValues = []) => setFields(mapIds(fieldsValues, keyName));
498
+ const cleanup = (ref) => !compact(get(ref, name, [])).length && unset(ref, name);
499
+ const updateDirtyFieldsWithDefaultValues = (updatedFieldArrayValues) => updatedFieldArrayValues &&
500
+ set(formStateRef.current.dirtyFields, name, setFieldArrayDirtyFields(omitKey(updatedFieldArrayValues), get(defaultValuesRef.current, name, []), get(formStateRef.current.dirtyFields, name, [])));
501
+ const batchStateUpdate = (method, args, updatedFieldArrayValues = [], shouldSet = true) => {
502
+ if (get(fieldsRef.current, name)) {
503
+ const output = method(get(fieldsRef.current, name), args.argA, args.argB);
504
+ shouldSet && set(fieldsRef.current, name, output);
392
505
  }
393
- else {
394
- const valueDate = ref.valueAsDate || new Date(inputValue);
395
- if (isString(maxOutput.value)) {
396
- exceedMax = valueDate > new Date(maxOutput.value);
397
- }
398
- if (isString(minOutput.value)) {
399
- exceedMin = valueDate < new Date(minOutput.value);
400
- }
506
+ if (Array.isArray(get(formStateRef.current.errors, name))) {
507
+ const output = method(get(formStateRef.current.errors, name), args.argA, args.argB);
508
+ shouldSet && set(formStateRef.current.errors, name, output);
509
+ cleanup(formStateRef.current.errors);
401
510
  }
402
- if (exceedMax || exceedMin) {
403
- getMinMaxMessage(!!exceedMax, maxOutput.message, minOutput.message, INPUT_VALIDATION_RULES.max, INPUT_VALIDATION_RULES.min);
404
- if (!validateAllFieldCriteria) {
405
- return error;
406
- }
511
+ if (readFormStateRef.current.touchedFields &&
512
+ get(formStateRef.current.touchedFields, name)) {
513
+ const output = method(get(formStateRef.current.touchedFields, name), args.argA, args.argB);
514
+ shouldSet && set(formStateRef.current.touchedFields, name, output);
515
+ cleanup(formStateRef.current.touchedFields);
407
516
  }
408
- }
409
- if (isString(inputValue) && !isEmpty && (maxLength || minLength)) {
410
- const maxLengthOutput = getValueAndMessage(maxLength);
411
- const minLengthOutput = getValueAndMessage(minLength);
412
- const exceedMax = !isNullOrUndefined(maxLengthOutput.value) &&
413
- inputValue.length > maxLengthOutput.value;
414
- const exceedMin = !isNullOrUndefined(minLengthOutput.value) &&
415
- inputValue.length < minLengthOutput.value;
416
- if (exceedMax || exceedMin) {
417
- getMinMaxMessage(exceedMax, maxLengthOutput.message, minLengthOutput.message);
418
- if (!validateAllFieldCriteria) {
419
- return error;
420
- }
517
+ if (readFormStateRef.current.dirtyFields ||
518
+ readFormStateRef.current.isDirty) {
519
+ set(formStateRef.current.dirtyFields, name, setFieldArrayDirtyFields(omitKey(updatedFieldArrayValues), get(defaultValuesRef.current, name, []), get(formStateRef.current.dirtyFields, name, [])));
520
+ updateDirtyFieldsWithDefaultValues(updatedFieldArrayValues);
521
+ cleanup(formStateRef.current.dirtyFields);
421
522
  }
422
- }
423
- if (isString(inputValue) && pattern && !isEmpty) {
424
- const { value: patternValue, message } = getValueAndMessage(pattern);
425
- if (isRegex(patternValue) && !patternValue.test(inputValue)) {
426
- error[name] = Object.assign({ type: INPUT_VALIDATION_RULES.pattern, message,
427
- ref }, appendErrorsCurry(INPUT_VALIDATION_RULES.pattern, message));
428
- if (!validateAllFieldCriteria) {
429
- return error;
430
- }
523
+ if (readFormStateRef.current.isValid) {
524
+ set(validFieldsRef.current, name, method(get(validFieldsRef.current, name, []), args.argA));
525
+ cleanup(validFieldsRef.current);
526
+ set(fieldsWithValidationRef.current, name, method(get(fieldsWithValidationRef.current, name, []), args.argA));
527
+ cleanup(fieldsWithValidationRef.current);
431
528
  }
432
- }
433
- if (validate) {
434
- const validateRef = isRadioOrCheckbox && refs ? refs[0] : ref;
435
- if (isFunction(validate)) {
436
- const result = await validate(inputValue);
437
- const validateError = getValidateError(result, validateRef);
438
- if (validateError) {
439
- error[name] = Object.assign(Object.assign({}, validateError), appendErrorsCurry(INPUT_VALIDATION_RULES.validate, validateError.message));
440
- if (!validateAllFieldCriteria) {
441
- return error;
442
- }
443
- }
529
+ formStateSubjectRef.current.next({
530
+ isDirty: getFormIsDirty(name, omitKey(updatedFieldArrayValues)),
531
+ errors: formStateRef.current.errors,
532
+ isValid: formStateRef.current.isValid,
533
+ });
534
+ };
535
+ const registerFieldArray = (values, index = 0, parentName = '') => values.forEach((appendValueItem, valueIndex) => Object.entries(appendValueItem).forEach(([key, value]) => {
536
+ const inputName = `${parentName || name}.${parentName ? valueIndex : index + valueIndex}.${key}`;
537
+ Array.isArray(value)
538
+ ? registerFieldArray(value, valueIndex, inputName)
539
+ : set(fieldsRef.current, inputName, {
540
+ _f: {
541
+ ref: {
542
+ name: inputName,
543
+ },
544
+ name: inputName,
545
+ value,
546
+ },
547
+ });
548
+ }));
549
+ const append$1 = (value, options) => {
550
+ const appendValue = Array.isArray(value) ? value : [value];
551
+ const updatedFieldArrayValues = append(getCurrentFieldsValues(), appendValue);
552
+ const currentIndex = updatedFieldArrayValues.length - appendValue.length;
553
+ setFieldsAndNotify(updatedFieldArrayValues);
554
+ batchStateUpdate(append, {
555
+ argA: fillEmptyArray(value),
556
+ }, updatedFieldArrayValues, false);
557
+ registerFieldArray(appendValue, currentIndex);
558
+ focusNameRef.current = getFocusDetail(currentIndex, options);
559
+ };
560
+ const prepend$1 = (value, options) => {
561
+ const prependValue = Array.isArray(value) ? value : [value];
562
+ const updatedFieldArrayValues = prepend(getCurrentFieldsValues(), prependValue);
563
+ setFieldsAndNotify(updatedFieldArrayValues);
564
+ batchStateUpdate(prepend, {
565
+ argA: fillEmptyArray(value),
566
+ }, updatedFieldArrayValues);
567
+ registerFieldArray(prependValue);
568
+ focusNameRef.current = getFocusDetail(0, options);
569
+ };
570
+ const remove = (index) => {
571
+ const updatedFieldArrayValues = removeArrayAt(getCurrentFieldsValues(), index);
572
+ resetFields(index);
573
+ setFieldsAndNotify(updatedFieldArrayValues);
574
+ batchStateUpdate(removeArrayAt, {
575
+ argA: index,
576
+ }, updatedFieldArrayValues);
577
+ };
578
+ const insert$1 = (index, value, options) => {
579
+ const insertValue = Array.isArray(value) ? value : [value];
580
+ const updatedFieldArrayValues = insert(getCurrentFieldsValues(), index, insertValue);
581
+ setFieldsAndNotify(updatedFieldArrayValues);
582
+ batchStateUpdate(insert, {
583
+ argA: index,
584
+ argB: fillEmptyArray(value),
585
+ }, updatedFieldArrayValues);
586
+ registerFieldArray(insertValue, index);
587
+ focusNameRef.current = getFocusDetail(index, options);
588
+ };
589
+ const swap = (indexA, indexB) => {
590
+ const fieldValues = getCurrentFieldsValues();
591
+ swapArrayAt(fieldValues, indexA, indexB);
592
+ batchStateUpdate(swapArrayAt, {
593
+ argA: indexA,
594
+ argB: indexB,
595
+ }, fieldValues, false);
596
+ setFieldsAndNotify(fieldValues);
597
+ };
598
+ const move = (from, to) => {
599
+ const fieldValues = getCurrentFieldsValues();
600
+ moveArrayAt(fieldValues, from, to);
601
+ setFieldsAndNotify(fieldValues);
602
+ batchStateUpdate(moveArrayAt, {
603
+ argA: from,
604
+ argB: to,
605
+ }, fieldValues, false);
606
+ };
607
+ React__namespace.useEffect(() => {
608
+ if (isWatchAllRef.current) {
609
+ formStateSubjectRef.current.next({});
444
610
  }
445
- else if (isObject(validate)) {
446
- let validationResult = {};
447
- for (const [key, validateFunction] of Object.entries(validate)) {
448
- if (!isEmptyObject(validationResult) && !validateAllFieldCriteria) {
611
+ else {
612
+ for (const watchField of watchFieldsRef.current) {
613
+ if (name.startsWith(watchField)) {
614
+ formStateSubjectRef.current.next({});
449
615
  break;
450
616
  }
451
- const validateResult = await validateFunction(inputValue);
452
- const validateError = getValidateError(validateResult, validateRef, key);
453
- if (validateError) {
454
- validationResult = Object.assign(Object.assign({}, validateError), appendErrorsCurry(key, validateError.message));
455
- if (validateAllFieldCriteria) {
456
- error[name] = validationResult;
457
- }
458
- }
459
- }
460
- if (!isEmptyObject(validationResult)) {
461
- error[name] = Object.assign({ ref: validateRef }, validationResult);
462
- if (!validateAllFieldCriteria) {
463
- return error;
464
- }
465
617
  }
466
618
  }
467
- }
468
- return error;
619
+ watchSubjectRef.current.next({
620
+ name,
621
+ value: get(getFieldsValues(fieldsRef, defaultValuesRef), name, []),
622
+ });
623
+ focusNameRef.current &&
624
+ focusFieldBy(fieldsRef.current, (key) => key.startsWith(focusNameRef.current));
625
+ focusNameRef.current = '';
626
+ fieldArraySubjectRef.current.next({
627
+ name,
628
+ fields: omitKey([...fields]),
629
+ });
630
+ }, [fields, name]);
631
+ React__namespace.useEffect(() => {
632
+ const fieldArraySubscription = fieldArraySubjectRef.current.subscribe({
633
+ next({ name: inputFieldArrayName, fields, isReset }) {
634
+ if (isReset) {
635
+ unset(fieldsRef.current, inputFieldArrayName || name);
636
+ inputFieldArrayName
637
+ ? set(fieldArrayDefaultValuesRef.current, inputFieldArrayName, fields)
638
+ : (fieldArrayDefaultValuesRef.current = fields);
639
+ setFieldsAndNotify(get(fieldArrayDefaultValuesRef.current, name));
640
+ }
641
+ },
642
+ });
643
+ !get(fieldsRef.current, name) && set(fieldsRef.current, name, []);
644
+ return () => {
645
+ fieldArrayDefaultValuesRef.current = getFieldsValues(fieldsRef);
646
+ fieldArraySubscription.unsubscribe();
647
+ };
648
+ }, []);
649
+ return {
650
+ swap: React__namespace.useCallback(swap, [name]),
651
+ move: React__namespace.useCallback(move, [name]),
652
+ prepend: React__namespace.useCallback(prepend$1, [name]),
653
+ append: React__namespace.useCallback(append$1, [name]),
654
+ remove: React__namespace.useCallback(remove, [name]),
655
+ insert: React__namespace.useCallback(insert$1, [name]),
656
+ fields: fields,
657
+ };
469
658
  };
470
659
 
471
- var skipValidation = ({ isOnBlur, isOnChange, isOnTouch, isTouched, isReValidateOnBlur, isReValidateOnChange, isBlurEvent, isSubmitted, isOnAll, }) => {
472
- if (isOnAll) {
473
- return false;
474
- }
475
- else if (!isSubmitted && isOnTouch) {
476
- return !(isTouched || isBlurEvent);
477
- }
478
- else if (isSubmitted ? isReValidateOnBlur : isOnBlur) {
479
- return !isBlurEvent;
660
+ function getFields(fieldsNames, fieldsRefs) {
661
+ const currentFields = {};
662
+ for (const name of fieldsNames) {
663
+ const field = get(fieldsRefs, name);
664
+ if (field) {
665
+ !isKey(name)
666
+ ? set(currentFields, name, field._f)
667
+ : (currentFields[name] = field._f);
668
+ }
480
669
  }
481
- else if (isSubmitted ? isReValidateOnChange : isOnChange) {
482
- return isBlurEvent;
670
+ return currentFields;
671
+ }
672
+
673
+ var isFileInput = (element) => element.type === 'file';
674
+
675
+ var isMultipleSelect = (element) => element.type === `${SELECT}-multiple`;
676
+
677
+ var isRadioInput = (element) => element.type === 'radio';
678
+
679
+ const defaultResult = {
680
+ value: false,
681
+ isValid: false,
682
+ };
683
+ const validResult = { value: true, isValid: true };
684
+ var getCheckboxValue = (options) => {
685
+ if (Array.isArray(options)) {
686
+ if (options.length > 1) {
687
+ const values = options
688
+ .filter((option) => option && option.checked && !option.disabled)
689
+ .map((option) => option.value);
690
+ return { value: values, isValid: !!values.length };
691
+ }
692
+ return options[0].checked && !options[0].disabled
693
+ ? // @ts-expect-error expected to work in the browser
694
+ options[0].attributes && !isUndefined(options[0].attributes.value)
695
+ ? isUndefined(options[0].value) || options[0].value === ''
696
+ ? validResult
697
+ : { value: options[0].value, isValid: true }
698
+ : validResult
699
+ : defaultResult;
483
700
  }
484
- return true;
701
+ return defaultResult;
485
702
  };
486
703
 
487
- var getNodeParentName = (name) => name.substring(0, name.search(/.\d/)) || name;
704
+ var getFieldValueAs = (value, { valueAsNumber, valueAsDate, setValueAs }) => valueAsNumber
705
+ ? value === ''
706
+ ? NaN
707
+ : +value
708
+ : valueAsDate
709
+ ? new Date(value)
710
+ : setValueAs
711
+ ? setValueAs(value)
712
+ : value;
488
713
 
489
- var getProxyFormState = (isProxyEnabled, formState, readFormStateRef, localReadFormStateRef, isRoot = true) => isProxyEnabled
490
- ? new Proxy(formState, {
491
- get: (obj, prop) => {
492
- if (prop in obj) {
493
- if (readFormStateRef.current[prop] !== VALIDATION_MODE.all) {
494
- readFormStateRef.current[prop] = isRoot
495
- ? VALIDATION_MODE.all
496
- : true;
497
- }
498
- localReadFormStateRef &&
499
- (localReadFormStateRef.current[prop] = true);
500
- return obj[prop];
501
- }
502
- return undefined;
503
- },
504
- })
505
- : formState;
714
+ var getMultipleSelectValue = (options) => [...options]
715
+ .filter(({ selected }) => selected)
716
+ .map(({ value }) => value);
506
717
 
507
- class Subscription {
508
- constructor() {
509
- this.tearDowns = [];
510
- }
511
- add(tearDown) {
512
- this.tearDowns.push(tearDown);
513
- }
514
- unsubscribe() {
515
- for (const teardown of this.tearDowns) {
516
- teardown();
718
+ const defaultReturn = {
719
+ isValid: false,
720
+ value: null,
721
+ };
722
+ var getRadioValue = (options) => Array.isArray(options)
723
+ ? options.reduce((previous, option) => option && option.checked && !option.disabled
724
+ ? {
725
+ isValid: true,
726
+ value: option.value,
517
727
  }
518
- this.tearDowns = [];
519
- }
520
- }
521
- class Subscriber {
522
- constructor(observer, subscription) {
523
- this.observer = observer;
524
- this.closed = false;
525
- subscription.add(() => (this.closed = true));
526
- }
527
- next(value) {
528
- if (!this.closed) {
529
- this.observer.next(value);
728
+ : previous, defaultReturn)
729
+ : defaultReturn;
730
+
731
+ function getFieldValue(field) {
732
+ if (field && field._f) {
733
+ const ref = field._f.ref;
734
+ if (ref.disabled) {
735
+ return;
530
736
  }
531
- }
532
- }
533
- class Subject {
534
- constructor() {
535
- this.observers = [];
536
- }
537
- next(value) {
538
- for (const observer of this.observers) {
539
- observer.next(value);
737
+ if (isFileInput(ref)) {
738
+ return ref.files;
540
739
  }
541
- }
542
- subscribe(observer) {
543
- const subscription = new Subscription();
544
- const subscriber = new Subscriber(observer, subscription);
545
- this.observers.push(subscriber);
546
- return subscription;
547
- }
548
- unsubscribe() {
549
- this.observers = [];
740
+ if (isRadioInput(ref)) {
741
+ return getRadioValue(field._f.refs).value;
742
+ }
743
+ if (isMultipleSelect(ref)) {
744
+ return getMultipleSelectValue(ref.options);
745
+ }
746
+ if (isCheckBoxInput(ref)) {
747
+ return getCheckboxValue(field._f.refs).value;
748
+ }
749
+ return getFieldValueAs(isUndefined(ref.value) ? field._f.ref.value : ref.value, field._f);
550
750
  }
551
751
  }
552
752
 
553
- var isWeb = typeof window !== UNDEFINED &&
554
- typeof window.HTMLElement !== UNDEFINED &&
555
- typeof document !== UNDEFINED;
556
-
557
- const isProxyEnabled = isWeb ? 'Proxy' in window : typeof Proxy !== UNDEFINED;
753
+ var isErrorStateChanged = ({ errors, name, error, validFields, fieldsWithValidation, }) => {
754
+ const isValid = isUndefined(error);
755
+ const previousError = get(errors, name);
756
+ return ((isValid && !!previousError) ||
757
+ (!isValid && !deepEqual(previousError, error, true)) ||
758
+ (isValid && get(fieldsWithValidation, name) && !get(validFields, name)));
759
+ };
558
760
 
559
- function baseGet(object, updatePath) {
560
- const length = updatePath.slice(0, -1).length;
561
- let index = 0;
562
- while (index < length) {
563
- object = isUndefined(object) ? index++ : object[updatePath[index++]];
761
+ var skipValidation = ({ isOnBlur, isOnChange, isOnTouch, isTouched, isReValidateOnBlur, isReValidateOnChange, isBlurEvent, isSubmitted, isOnAll, }) => {
762
+ if (isOnAll) {
763
+ return false;
564
764
  }
565
- return object;
566
- }
567
- function unset(object, path) {
568
- const updatePath = isKey(path) ? [path] : stringToPath(path);
569
- const childObject = updatePath.length == 1 ? object : baseGet(object, updatePath);
570
- const key = updatePath[updatePath.length - 1];
571
- let previousObjRef;
572
- if (childObject) {
573
- delete childObject[key];
765
+ else if (!isSubmitted && isOnTouch) {
766
+ return !(isTouched || isBlurEvent);
574
767
  }
575
- for (let k = 0; k < updatePath.slice(0, -1).length; k++) {
576
- let index = -1;
577
- let objectRef;
578
- const currentPaths = updatePath.slice(0, -(k + 1));
579
- const currentPathsLength = currentPaths.length - 1;
580
- if (k > 0) {
581
- previousObjRef = object;
582
- }
583
- while (++index < currentPaths.length) {
584
- const item = currentPaths[index];
585
- objectRef = objectRef ? objectRef[item] : object[item];
586
- if (currentPathsLength === index &&
587
- ((isObject(objectRef) && isEmptyObject(objectRef)) ||
588
- (Array.isArray(objectRef) &&
589
- !objectRef.filter((data) => (isObject(data) && !isEmptyObject(data)) || isBoolean(data)).length))) {
590
- previousObjRef ? delete previousObjRef[item] : delete object[item];
591
- }
592
- previousObjRef = objectRef;
593
- }
768
+ else if (isSubmitted ? isReValidateOnBlur : isOnBlur) {
769
+ return !isBlurEvent;
594
770
  }
595
- return object;
596
- }
771
+ else if (isSubmitted ? isReValidateOnChange : isOnChange) {
772
+ return isBlurEvent;
773
+ }
774
+ return true;
775
+ };
597
776
 
598
- var getValidationModes = (mode) => ({
599
- isOnSubmit: !mode || mode === VALIDATION_MODE.onSubmit,
600
- isOnBlur: mode === VALIDATION_MODE.onBlur,
601
- isOnChange: mode === VALIDATION_MODE.onChange,
602
- isOnAll: mode === VALIDATION_MODE.all,
603
- isOnTouch: mode === VALIDATION_MODE.onTouched,
604
- });
777
+ var isFunction = (value) => typeof value === 'function';
605
778
 
606
- var isRadioOrCheckboxFunction = (ref) => isRadioInput(ref) || isCheckBoxInput(ref);
779
+ var isString = (value) => typeof value === 'string';
607
780
 
608
- var isHTMLElement = (value) => value instanceof HTMLElement;
781
+ var isMessage = (value) => isString(value) || React__namespace.isValidElement(value);
609
782
 
610
- function getFields(fieldsNames, fieldsRefs) {
611
- const currentFields = {};
612
- for (const name of fieldsNames) {
613
- const field = get(fieldsRefs, name);
614
- if (field) {
615
- !isKey(name)
616
- ? set(currentFields, name, field._f)
617
- : (currentFields[name] = field._f);
618
- }
783
+ var isRegex = (value) => value instanceof RegExp;
784
+
785
+ function getValidateError(result, ref, type = 'validate') {
786
+ if (isMessage(result) || (isBoolean(result) && !result)) {
787
+ return {
788
+ type,
789
+ message: isMessage(result) ? result : '',
790
+ ref,
791
+ };
619
792
  }
620
- return currentFields;
621
793
  }
622
794
 
623
- const isWindowUndefined = typeof window === UNDEFINED;
624
- function useForm({ mode = VALIDATION_MODE.onSubmit, reValidateMode = VALIDATION_MODE.onChange, resolver, context, defaultValues = {}, shouldFocusError = true, criteriaMode, } = {}) {
625
- const fieldsRef = React__namespace.useRef({});
626
- const fieldsNamesRef = React__namespace.useRef(new Set());
627
- const formStateSubjectRef = React__namespace.useRef(new Subject());
628
- const watchSubjectRef = React__namespace.useRef(new Subject());
629
- const controllerSubjectRef = React__namespace.useRef(new Subject());
630
- const fieldArraySubjectRef = React__namespace.useRef(new Subject());
631
- const fieldArrayDefaultValuesRef = React__namespace.useRef({});
632
- const watchFieldsRef = React__namespace.useRef(new Set());
633
- const isMountedRef = React__namespace.useRef(false);
634
- const fieldsWithValidationRef = React__namespace.useRef({});
635
- const validFieldsRef = React__namespace.useRef({});
636
- const defaultValuesRef = React__namespace.useRef(defaultValues);
637
- const isWatchAllRef = React__namespace.useRef(false);
638
- const contextRef = React__namespace.useRef(context);
639
- const resolverRef = React__namespace.useRef(resolver);
640
- const fieldArrayNamesRef = React__namespace.useRef(new Set());
641
- const validationMode = getValidationModes(mode);
642
- const isValidateAllFieldCriteria = criteriaMode === VALIDATION_MODE.all;
643
- const [formState, setFormState] = React__namespace.useState({
644
- isDirty: false,
645
- isValidating: false,
646
- dirtyFields: {},
647
- isSubmitted: false,
795
+ var getValueAndMessage = (validationData) => isObject(validationData) && !isRegex(validationData)
796
+ ? validationData
797
+ : {
798
+ value: validationData,
799
+ message: '',
800
+ };
801
+
802
+ var validateField = async ({ _f: { ref, refs, required, maxLength, minLength, min, max, pattern, validate, name, value: inputValue, }, }, validateAllFieldCriteria) => {
803
+ const error = {};
804
+ const isRadio = isRadioInput(ref);
805
+ const isCheckBox = isCheckBoxInput(ref);
806
+ const isRadioOrCheckbox = isRadio || isCheckBox;
807
+ const isEmpty = inputValue === '' || (Array.isArray(inputValue) && !inputValue.length);
808
+ const appendErrorsCurry = appendErrors.bind(null, name, validateAllFieldCriteria, error);
809
+ const getMinMaxMessage = (exceedMax, maxLengthMessage, minLengthMessage, maxType = INPUT_VALIDATION_RULES.maxLength, minType = INPUT_VALIDATION_RULES.minLength) => {
810
+ const message = exceedMax ? maxLengthMessage : minLengthMessage;
811
+ error[name] = Object.assign({ type: exceedMax ? maxType : minType, message,
812
+ ref }, appendErrorsCurry(exceedMax ? maxType : minType, message));
813
+ };
814
+ if (required &&
815
+ ((!isRadio && !isCheckBox && (isEmpty || isNullOrUndefined(inputValue))) ||
816
+ (isBoolean(inputValue) && !inputValue) ||
817
+ (isCheckBox && !getCheckboxValue(refs).isValid) ||
818
+ (isRadio && !getRadioValue(refs).isValid))) {
819
+ const { value, message } = isMessage(required)
820
+ ? { value: !!required, message: required }
821
+ : getValueAndMessage(required);
822
+ if (value) {
823
+ error[name] = Object.assign({ type: INPUT_VALIDATION_RULES.required, message, ref: isRadioOrCheckbox ? (refs || [])[0] || {} : ref }, appendErrorsCurry(INPUT_VALIDATION_RULES.required, message));
824
+ if (!validateAllFieldCriteria) {
825
+ return error;
826
+ }
827
+ }
828
+ }
829
+ if ((!isNullOrUndefined(min) || !isNullOrUndefined(max)) &&
830
+ inputValue !== '') {
831
+ let exceedMax;
832
+ let exceedMin;
833
+ const maxOutput = getValueAndMessage(max);
834
+ const minOutput = getValueAndMessage(min);
835
+ if (!isNaN(inputValue)) {
836
+ const valueNumber = ref.valueAsNumber || parseFloat(inputValue);
837
+ if (!isNullOrUndefined(maxOutput.value)) {
838
+ exceedMax = valueNumber > maxOutput.value;
839
+ }
840
+ if (!isNullOrUndefined(minOutput.value)) {
841
+ exceedMin = valueNumber < minOutput.value;
842
+ }
843
+ }
844
+ else {
845
+ const valueDate = ref.valueAsDate || new Date(inputValue);
846
+ if (isString(maxOutput.value)) {
847
+ exceedMax = valueDate > new Date(maxOutput.value);
848
+ }
849
+ if (isString(minOutput.value)) {
850
+ exceedMin = valueDate < new Date(minOutput.value);
851
+ }
852
+ }
853
+ if (exceedMax || exceedMin) {
854
+ getMinMaxMessage(!!exceedMax, maxOutput.message, minOutput.message, INPUT_VALIDATION_RULES.max, INPUT_VALIDATION_RULES.min);
855
+ if (!validateAllFieldCriteria) {
856
+ return error;
857
+ }
858
+ }
859
+ }
860
+ if (isString(inputValue) && !isEmpty && (maxLength || minLength)) {
861
+ const maxLengthOutput = getValueAndMessage(maxLength);
862
+ const minLengthOutput = getValueAndMessage(minLength);
863
+ const exceedMax = !isNullOrUndefined(maxLengthOutput.value) &&
864
+ inputValue.length > maxLengthOutput.value;
865
+ const exceedMin = !isNullOrUndefined(minLengthOutput.value) &&
866
+ inputValue.length < minLengthOutput.value;
867
+ if (exceedMax || exceedMin) {
868
+ getMinMaxMessage(exceedMax, maxLengthOutput.message, minLengthOutput.message);
869
+ if (!validateAllFieldCriteria) {
870
+ return error;
871
+ }
872
+ }
873
+ }
874
+ if (isString(inputValue) && pattern && !isEmpty) {
875
+ const { value: patternValue, message } = getValueAndMessage(pattern);
876
+ if (isRegex(patternValue) && !patternValue.test(inputValue)) {
877
+ error[name] = Object.assign({ type: INPUT_VALIDATION_RULES.pattern, message,
878
+ ref }, appendErrorsCurry(INPUT_VALIDATION_RULES.pattern, message));
879
+ if (!validateAllFieldCriteria) {
880
+ return error;
881
+ }
882
+ }
883
+ }
884
+ if (validate) {
885
+ const validateRef = isRadioOrCheckbox && refs ? refs[0] : ref;
886
+ if (isFunction(validate)) {
887
+ const result = await validate(inputValue);
888
+ const validateError = getValidateError(result, validateRef);
889
+ if (validateError) {
890
+ error[name] = Object.assign(Object.assign({}, validateError), appendErrorsCurry(INPUT_VALIDATION_RULES.validate, validateError.message));
891
+ if (!validateAllFieldCriteria) {
892
+ return error;
893
+ }
894
+ }
895
+ }
896
+ else if (isObject(validate)) {
897
+ let validationResult = {};
898
+ for (const [key, validateFunction] of Object.entries(validate)) {
899
+ if (!isEmptyObject(validationResult) && !validateAllFieldCriteria) {
900
+ break;
901
+ }
902
+ const validateResult = await validateFunction(inputValue);
903
+ const validateError = getValidateError(validateResult, validateRef, key);
904
+ if (validateError) {
905
+ validationResult = Object.assign(Object.assign({}, validateError), appendErrorsCurry(key, validateError.message));
906
+ if (validateAllFieldCriteria) {
907
+ error[name] = validationResult;
908
+ }
909
+ }
910
+ }
911
+ if (!isEmptyObject(validationResult)) {
912
+ error[name] = Object.assign({ ref: validateRef }, validationResult);
913
+ if (!validateAllFieldCriteria) {
914
+ return error;
915
+ }
916
+ }
917
+ }
918
+ }
919
+ return error;
920
+ };
921
+
922
+ var getValidationModes = (mode) => ({
923
+ isOnSubmit: !mode || mode === VALIDATION_MODE.onSubmit,
924
+ isOnBlur: mode === VALIDATION_MODE.onBlur,
925
+ isOnChange: mode === VALIDATION_MODE.onChange,
926
+ isOnAll: mode === VALIDATION_MODE.all,
927
+ isOnTouch: mode === VALIDATION_MODE.onTouched,
928
+ });
929
+
930
+ var isHTMLElement = (value) => value instanceof HTMLElement;
931
+
932
+ var isRadioOrCheckboxFunction = (ref) => isRadioInput(ref) || isCheckBoxInput(ref);
933
+
934
+ class Subscription {
935
+ constructor() {
936
+ this.tearDowns = [];
937
+ }
938
+ add(tearDown) {
939
+ this.tearDowns.push(tearDown);
940
+ }
941
+ unsubscribe() {
942
+ for (const teardown of this.tearDowns) {
943
+ teardown();
944
+ }
945
+ this.tearDowns = [];
946
+ }
947
+ }
948
+ class Subscriber {
949
+ constructor(observer, subscription) {
950
+ this.observer = observer;
951
+ this.closed = false;
952
+ subscription.add(() => (this.closed = true));
953
+ }
954
+ next(value) {
955
+ if (!this.closed) {
956
+ this.observer.next(value);
957
+ }
958
+ }
959
+ }
960
+ class Subject {
961
+ constructor() {
962
+ this.observers = [];
963
+ }
964
+ next(value) {
965
+ for (const observer of this.observers) {
966
+ observer.next(value);
967
+ }
968
+ }
969
+ subscribe(observer) {
970
+ const subscription = new Subscription();
971
+ const subscriber = new Subscriber(observer, subscription);
972
+ this.observers.push(subscriber);
973
+ return subscription;
974
+ }
975
+ unsubscribe() {
976
+ this.observers = [];
977
+ }
978
+ }
979
+
980
+ const isWindowUndefined = typeof window === UNDEFINED;
981
+ function useForm({ mode = VALIDATION_MODE.onSubmit, reValidateMode = VALIDATION_MODE.onChange, resolver, context, defaultValues = {}, shouldFocusError = true, criteriaMode, } = {}) {
982
+ const fieldsRef = React__namespace.useRef({});
983
+ const fieldsNamesRef = React__namespace.useRef(new Set());
984
+ const formStateSubjectRef = React__namespace.useRef(new Subject());
985
+ const watchSubjectRef = React__namespace.useRef(new Subject());
986
+ const controllerSubjectRef = React__namespace.useRef(new Subject());
987
+ const fieldArraySubjectRef = React__namespace.useRef(new Subject());
988
+ const fieldArrayDefaultValuesRef = React__namespace.useRef({});
989
+ const watchFieldsRef = React__namespace.useRef(new Set());
990
+ const isMountedRef = React__namespace.useRef(false);
991
+ const fieldsWithValidationRef = React__namespace.useRef({});
992
+ const validFieldsRef = React__namespace.useRef({});
993
+ const defaultValuesRef = React__namespace.useRef(defaultValues);
994
+ const isWatchAllRef = React__namespace.useRef(false);
995
+ const contextRef = React__namespace.useRef(context);
996
+ const resolverRef = React__namespace.useRef(resolver);
997
+ const fieldArrayNamesRef = React__namespace.useRef(new Set());
998
+ const validationMode = getValidationModes(mode);
999
+ const isValidateAllFieldCriteria = criteriaMode === VALIDATION_MODE.all;
1000
+ const [formState, setFormState] = React__namespace.useState({
1001
+ isDirty: false,
1002
+ isValidating: false,
1003
+ dirtyFields: {},
1004
+ isSubmitted: false,
648
1005
  submitCount: 0,
649
1006
  touchedFields: {},
650
1007
  isSubmitting: false,
@@ -737,7 +1094,7 @@ function useForm({ mode = VALIDATION_MODE.onSubmit, reValidateMode = VALIDATION_
737
1094
  name,
738
1095
  });
739
1096
  }
740
- options.shouldDirty && updateAndGetDirtyState(name);
1097
+ options.shouldDirty && updateAndGetDirtyState(name, value);
741
1098
  options.shouldValidate && trigger(name);
742
1099
  }
743
1100
  }, []);
@@ -749,17 +1106,18 @@ function useForm({ mode = VALIDATION_MODE.onSubmit, reValidateMode = VALIDATION_
749
1106
  }
750
1107
  return false;
751
1108
  }, []);
752
- const updateAndGetDirtyState = React__namespace.useCallback((name, shouldRender = true) => {
1109
+ const updateAndGetDirtyState = React__namespace.useCallback((name, inputValue, shouldRender = true) => {
753
1110
  if (readFormStateRef.current.isDirty ||
754
1111
  readFormStateRef.current.dirtyFields) {
755
- const isFieldDirty = !deepEqual(get(defaultValuesRef.current, name), getFieldValue(get(fieldsRef.current, name)));
1112
+ const isFieldDirty = !deepEqual(get(defaultValuesRef.current, name), inputValue);
756
1113
  const isDirtyFieldExist = get(formStateRef.current.dirtyFields, name);
757
1114
  const previousIsDirty = formStateRef.current.isDirty;
758
1115
  isFieldDirty
759
1116
  ? set(formStateRef.current.dirtyFields, name, true)
760
1117
  : unset(formStateRef.current.dirtyFields, name);
1118
+ formStateRef.current.isDirty = getFormIsDirty();
761
1119
  const state = {
762
- isDirty: getFormIsDirty(),
1120
+ isDirty: formStateRef.current.isDirty,
763
1121
  dirtyFields: formStateRef.current.dirtyFields,
764
1122
  };
765
1123
  const isChanged = (readFormStateRef.current.isDirty &&
@@ -880,8 +1238,11 @@ function useForm({ mode = VALIDATION_MODE.onSubmit, reValidateMode = VALIDATION_
880
1238
  isDirty: getFormIsDirty(name, value),
881
1239
  });
882
1240
  }
1241
+ !value.length &&
1242
+ set(fieldsRef.current, name, []) &&
1243
+ set(fieldArrayDefaultValuesRef.current, name, []);
883
1244
  }
884
- field && !field._f
1245
+ (field && !field._f) || isFieldArray
885
1246
  ? setInternalValues(name, value, isFieldArray ? {} : options)
886
1247
  : setFieldValue(name, value, options, true, !field);
887
1248
  isFieldWatched(name) && formStateSubjectRef.current.next({});
@@ -902,7 +1263,7 @@ function useForm({ mode = VALIDATION_MODE.onSubmit, reValidateMode = VALIDATION_
902
1263
  if (!isUndefined(inputValue)) {
903
1264
  field._f.value = inputValue;
904
1265
  }
905
- const state = updateAndGetDirtyState(name, false);
1266
+ const state = updateAndGetDirtyState(name, field._f.value, false);
906
1267
  if (isBlurEvent && !get(formStateRef.current.touchedFields, name)) {
907
1268
  set(formStateRef.current.touchedFields, name, true);
908
1269
  state.touchedFields = formStateRef.current.touchedFields;
@@ -1059,7 +1420,8 @@ function useForm({ mode = VALIDATION_MODE.onSubmit, reValidateMode = VALIDATION_
1059
1420
  ? Array.isArray(field._f.refs) &&
1060
1421
  compact(field._f.refs).find((option) => ref.value === option.value && option === ref)
1061
1422
  : ref === field._f.ref) ||
1062
- !field) {
1423
+ !field ||
1424
+ (isWeb && isHTMLElement(field._f.ref) && !isHTMLElement(ref))) {
1063
1425
  return;
1064
1426
  }
1065
1427
  field = {
@@ -1093,13 +1455,15 @@ function useForm({ mode = VALIDATION_MODE.onSubmit, reValidateMode = VALIDATION_
1093
1455
  }
1094
1456
  };
1095
1457
  const register = React__namespace.useCallback((name, options) => {
1458
+ const isInitialRegister = !get(fieldsRef.current, name);
1096
1459
  set(fieldsRef.current, name, {
1097
- _f: Object.assign(Object.assign(Object.assign({}, (get(fieldsRef.current, name)
1098
- ? Object.assign({ ref: get(fieldsRef.current, name)._f.ref }, get(fieldsRef.current, name)._f) : { ref: { name } })), { name }), options),
1460
+ _f: Object.assign(Object.assign(Object.assign({}, (isInitialRegister
1461
+ ? { ref: { name } }
1462
+ : Object.assign({ ref: (get(fieldsRef.current, name)._f || {}).ref }, get(fieldsRef.current, name)._f))), { name }), options),
1099
1463
  });
1100
1464
  options && set(fieldsWithValidationRef.current, name, true);
1101
1465
  fieldsNamesRef.current.add(name);
1102
- updateValueAndGetDefault(name);
1466
+ isInitialRegister && updateValueAndGetDefault(name);
1103
1467
  return isWindowUndefined
1104
1468
  ? { name: name }
1105
1469
  : {
@@ -1139,487 +1503,135 @@ function useForm({ mode = VALIDATION_MODE.onSubmit, reValidateMode = VALIDATION_
1139
1503
  await onValid(fieldValues, e);
1140
1504
  }
1141
1505
  else {
1142
- onInvalid && (await onInvalid(formStateRef.current.errors, e));
1143
- shouldFocusError &&
1144
- focusFieldBy(fieldsRef.current, (key) => get(formStateRef.current.errors, key), fieldsNamesRef.current);
1145
- }
1146
- }
1147
- finally {
1148
- formStateRef.current.isSubmitted = true;
1149
- formStateSubjectRef.current.next({
1150
- isSubmitted: true,
1151
- isSubmitting: false,
1152
- isSubmitSuccessful: isEmptyObject(formStateRef.current.errors),
1153
- submitCount: formStateRef.current.submitCount + 1,
1154
- errors: formStateRef.current.errors,
1155
- });
1156
- }
1157
- }, [shouldFocusError, isValidateAllFieldCriteria, criteriaMode]);
1158
- const resetFromState = React__namespace.useCallback(({ keepErrors, keepDirty, keepIsSubmitted, keepTouched, keepIsValid, keepSubmitCount, }) => {
1159
- if (!keepIsValid) {
1160
- validFieldsRef.current = {};
1161
- fieldsWithValidationRef.current = {};
1162
- }
1163
- watchFieldsRef.current = new Set();
1164
- isWatchAllRef.current = false;
1165
- formStateSubjectRef.current.next({
1166
- submitCount: keepSubmitCount ? formStateRef.current.submitCount : 0,
1167
- isDirty: keepDirty ? formStateRef.current.isDirty : false,
1168
- isSubmitted: keepIsSubmitted ? formStateRef.current.isSubmitted : false,
1169
- isValid: keepIsValid
1170
- ? formStateRef.current.isValid
1171
- : !validationMode.isOnSubmit,
1172
- dirtyFields: keepDirty ? formStateRef.current.dirtyFields : {},
1173
- touchedFields: keepTouched ? formStateRef.current.touchedFields : {},
1174
- errors: keepErrors ? formStateRef.current.errors : {},
1175
- isSubmitting: false,
1176
- isSubmitSuccessful: false,
1177
- });
1178
- }, []);
1179
- const reset = (values, keepStateOptions = {}) => {
1180
- const updatedValues = values || defaultValuesRef.current;
1181
- if (isWeb && !keepStateOptions.keepValues) {
1182
- for (const field of Object.values(fieldsRef.current)) {
1183
- if (field && field._f) {
1184
- const inputRef = Array.isArray(field._f.refs)
1185
- ? field._f.refs[0]
1186
- : field._f.ref;
1187
- if (isHTMLElement(inputRef)) {
1188
- try {
1189
- inputRef.closest('form').reset();
1190
- break;
1191
- }
1192
- catch (_a) { }
1193
- }
1194
- }
1195
- }
1196
- }
1197
- !keepStateOptions.keepDefaultValues &&
1198
- (defaultValuesRef.current = Object.assign({}, updatedValues));
1199
- if (!keepStateOptions.keepValues) {
1200
- fieldsRef.current = {};
1201
- controllerSubjectRef.current.next({
1202
- values: Object.assign({}, updatedValues),
1203
- });
1204
- watchSubjectRef.current.next({
1205
- value: Object.assign({}, updatedValues),
1206
- });
1207
- fieldArraySubjectRef.current.next({
1208
- fields: Object.assign({}, updatedValues),
1209
- isReset: true,
1210
- });
1211
- }
1212
- resetFromState(keepStateOptions);
1213
- };
1214
- React__namespace.useEffect(() => {
1215
- isMountedRef.current = true;
1216
- const formStateSubscription = formStateSubjectRef.current.subscribe({
1217
- next(formState = {}) {
1218
- if (shouldRenderFormState(formState, readFormStateRef.current, true)) {
1219
- formStateRef.current = Object.assign(Object.assign({}, formStateRef.current), formState);
1220
- setFormState(formStateRef.current);
1221
- }
1222
- },
1223
- });
1224
- const useFieldArraySubscription = fieldArraySubjectRef.current.subscribe({
1225
- next(state) {
1226
- if (state.fields && state.name && readFormStateRef.current.isValid) {
1227
- const values = getFieldsValues(fieldsRef);
1228
- set(values, state.name, state.fields);
1229
- updateIsValid(values);
1230
- }
1231
- },
1232
- });
1233
- resolverRef.current && readFormStateRef.current.isValid && updateIsValid();
1234
- return () => {
1235
- watchSubjectRef.current.unsubscribe();
1236
- formStateSubscription.unsubscribe();
1237
- useFieldArraySubscription.unsubscribe();
1238
- };
1239
- }, []);
1240
- return {
1241
- control: React__namespace.useMemo(() => ({
1242
- register,
1243
- isWatchAllRef,
1244
- watchFieldsRef,
1245
- getFormIsDirty,
1246
- formStateSubjectRef,
1247
- fieldArraySubjectRef,
1248
- controllerSubjectRef,
1249
- watchSubjectRef,
1250
- watchInternal,
1251
- fieldsRef,
1252
- validFieldsRef,
1253
- fieldsWithValidationRef,
1254
- fieldArrayNamesRef,
1255
- readFormStateRef,
1256
- formStateRef,
1257
- defaultValuesRef,
1258
- fieldArrayDefaultValuesRef,
1259
- }), []),
1260
- formState: getProxyFormState(isProxyEnabled, formState, readFormStateRef),
1261
- trigger,
1262
- register,
1263
- handleSubmit,
1264
- watch: React__namespace.useCallback(watch, []),
1265
- setValue: React__namespace.useCallback(setValue, [setInternalValues]),
1266
- getValues: React__namespace.useCallback(getValues, []),
1267
- reset: React__namespace.useCallback(reset, []),
1268
- clearErrors: React__namespace.useCallback(clearErrors, []),
1269
- unregister: React__namespace.useCallback(unregister, []),
1270
- setError: React__namespace.useCallback(setError, []),
1271
- };
1272
- }
1273
-
1274
- const FormContext = React__namespace.createContext(null);
1275
- FormContext.displayName = 'RHFContext';
1276
- const useFormContext = () => React__namespace.useContext(FormContext);
1277
- const FormProvider = (props) => (React__namespace.createElement(FormContext.Provider, { value: omit(props, 'children') }, props.children));
1278
-
1279
- var generateId = () => {
1280
- const d = typeof performance === UNDEFINED ? Date.now() : performance.now() * 1000;
1281
- return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {
1282
- const r = (Math.random() * 16 + d) % 16 | 0;
1283
- return (c == 'x' ? r : (r & 0x3) | 0x8).toString(16);
1284
- });
1285
- };
1286
-
1287
- var mapIds = (values = [], keyName) => values.map((value) => (Object.assign({ [keyName]: (value && value[keyName]) || generateId() }, value)));
1288
-
1289
- function removeAtIndexes(data, indexes) {
1290
- let i = 0;
1291
- const temp = [...data];
1292
- for (const index of indexes) {
1293
- temp.splice(index - i, 1);
1294
- i++;
1295
- }
1296
- return compact(temp).length ? temp : [];
1297
- }
1298
- var removeArrayAt = (data, index) => isUndefined(index)
1299
- ? []
1300
- : removeAtIndexes(data, (Array.isArray(index) ? index : [index]).sort((a, b) => a - b));
1301
-
1302
- var moveArrayAt = (data, from, to) => {
1303
- if (Array.isArray(data)) {
1304
- if (isUndefined(data[to])) {
1305
- data[to] = undefined;
1306
- }
1307
- data.splice(to, 0, data.splice(from, 1)[0]);
1308
- return data;
1309
- }
1310
- return [];
1311
- };
1312
-
1313
- var swapArrayAt = (data, indexA, indexB) => {
1314
- data[indexA] = [data[indexB], (data[indexB] = data[indexA])][0];
1315
- };
1316
-
1317
- function prepend(data, value) {
1318
- return [...(Array.isArray(value) ? value : [value]), ...data];
1319
- }
1320
-
1321
- function append(data, value) {
1322
- return [...data, ...(Array.isArray(value) ? value : [value])];
1323
- }
1324
-
1325
- function insert(data, index, value) {
1326
- return [
1327
- ...data.slice(0, index),
1328
- ...(Array.isArray(value) ? value : [value]),
1329
- ...data.slice(index),
1330
- ];
1331
- }
1332
-
1333
- var fillEmptyArray = (value) => Array.isArray(value) ? Array(value.length).fill(undefined) : undefined;
1334
-
1335
- const useFieldArray = ({ control, name, keyName = 'id', }) => {
1336
- const methods = useFormContext();
1337
- const focusNameRef = React__namespace.useRef('');
1338
- const { isWatchAllRef, watchFieldsRef, getFormIsDirty, watchSubjectRef, fieldArraySubjectRef, fieldArrayNamesRef, fieldsRef, defaultValuesRef, formStateRef, formStateSubjectRef, readFormStateRef, validFieldsRef, fieldsWithValidationRef, fieldArrayDefaultValuesRef, } = control || methods.control;
1339
- const [fields, setFields] = React__namespace.useState(mapIds(get(fieldArrayDefaultValuesRef.current, getNodeParentName(name))
1340
- ? get(fieldArrayDefaultValuesRef.current, name, [])
1341
- : get(defaultValuesRef.current, name, []), keyName));
1342
- set(fieldArrayDefaultValuesRef.current, name, [...fields]);
1343
- fieldArrayNamesRef.current.add(name);
1344
- const omitKey = (fields) => fields.map((field) => omit((field || {}), keyName));
1345
- const getCurrentFieldsValues = () => {
1346
- const values = get(getFieldsValues(fieldsRef, defaultValuesRef), name, []);
1347
- return mapIds(get(fieldArrayDefaultValuesRef.current, name, []).map((item, index) => (Object.assign(Object.assign({}, item), values[index]))), keyName);
1348
- };
1349
- const getFocusDetail = (index, options) => options
1350
- ? !isUndefined(options.focusIndex)
1351
- ? `${name}.${options.focusIndex}`
1352
- : options.focusName
1353
- ? options.focusName
1354
- : !options.shouldFocus
1355
- ? ''
1356
- : `${name}.${index}`
1357
- : `${name}.${index}`;
1358
- const resetFields = (index) => (Array.isArray(index) ? index : [index]).forEach((currentIndex) => set(fieldsRef.current, `${name}${isUndefined(currentIndex) ? '' : `.${currentIndex}`}`, isUndefined(currentIndex) ? [] : undefined));
1359
- const setFieldsAndNotify = (fieldsValues = []) => setFields(mapIds(fieldsValues, keyName));
1360
- const cleanup = (ref) => !compact(get(ref, name, [])).length && unset(ref, name);
1361
- const updateDirtyFieldsWithDefaultValues = (updatedFieldArrayValues) => updatedFieldArrayValues &&
1362
- set(formStateRef.current.dirtyFields, name, setFieldArrayDirtyFields(omitKey(updatedFieldArrayValues), get(defaultValuesRef.current, name, []), get(formStateRef.current.dirtyFields, name, [])));
1363
- const batchStateUpdate = (method, args, updatedFieldArrayValues = [], shouldSet = true) => {
1364
- if (get(fieldsRef.current, name)) {
1365
- const output = method(get(fieldsRef.current, name), args.argA, args.argB);
1366
- shouldSet && set(fieldsRef.current, name, output);
1367
- }
1368
- if (Array.isArray(get(formStateRef.current.errors, name))) {
1369
- const output = method(get(formStateRef.current.errors, name), args.argA, args.argB);
1370
- shouldSet && set(formStateRef.current.errors, name, output);
1371
- cleanup(formStateRef.current.errors);
1372
- }
1373
- if (readFormStateRef.current.touchedFields &&
1374
- get(formStateRef.current.touchedFields, name)) {
1375
- const output = method(get(formStateRef.current.touchedFields, name), args.argA, args.argB);
1376
- shouldSet && set(formStateRef.current.touchedFields, name, output);
1377
- cleanup(formStateRef.current.touchedFields);
1378
- }
1379
- if (readFormStateRef.current.dirtyFields ||
1380
- readFormStateRef.current.isDirty) {
1381
- set(formStateRef.current.dirtyFields, name, setFieldArrayDirtyFields(omitKey(updatedFieldArrayValues), get(defaultValuesRef.current, name, []), get(formStateRef.current.dirtyFields, name, [])));
1382
- updateDirtyFieldsWithDefaultValues(updatedFieldArrayValues);
1383
- cleanup(formStateRef.current.dirtyFields);
1384
- }
1385
- if (readFormStateRef.current.isValid) {
1386
- set(validFieldsRef.current, name, method(get(validFieldsRef.current, name, []), args.argA));
1387
- cleanup(validFieldsRef.current);
1388
- set(fieldsWithValidationRef.current, name, method(get(fieldsWithValidationRef.current, name, []), args.argA));
1389
- cleanup(fieldsWithValidationRef.current);
1390
- }
1391
- formStateSubjectRef.current.next({
1392
- isDirty: getFormIsDirty(name, omitKey(updatedFieldArrayValues)),
1393
- errors: formStateRef.current.errors,
1394
- isValid: formStateRef.current.isValid,
1395
- });
1396
- };
1397
- const registerFieldArray = (values, index = 0, parentName = '') => values.forEach((appendValueItem, valueIndex) => Object.entries(appendValueItem).forEach(([key, value]) => {
1398
- const inputName = `${parentName || name}.${parentName ? valueIndex : index + valueIndex}.${key}`;
1399
- Array.isArray(value)
1400
- ? registerFieldArray(value, valueIndex, inputName)
1401
- : set(fieldsRef.current, inputName, {
1402
- _f: {
1403
- ref: {
1404
- name: inputName,
1405
- },
1406
- name: inputName,
1407
- value,
1408
- },
1409
- });
1410
- }));
1411
- const append$1 = (value, options) => {
1412
- const appendValue = Array.isArray(value) ? value : [value];
1413
- const updatedFieldArrayValues = append(getCurrentFieldsValues(), appendValue);
1414
- const currentIndex = updatedFieldArrayValues.length - appendValue.length;
1415
- setFieldsAndNotify(updatedFieldArrayValues);
1416
- batchStateUpdate(append, {
1417
- argA: fillEmptyArray(value),
1418
- }, updatedFieldArrayValues, false);
1419
- registerFieldArray(appendValue, currentIndex);
1420
- focusNameRef.current = getFocusDetail(currentIndex, options);
1421
- };
1422
- const prepend$1 = (value, options) => {
1423
- const prependValue = Array.isArray(value) ? value : [value];
1424
- const updatedFieldArrayValues = prepend(getCurrentFieldsValues(), prependValue);
1425
- setFieldsAndNotify(updatedFieldArrayValues);
1426
- batchStateUpdate(prepend, {
1427
- argA: fillEmptyArray(value),
1428
- }, updatedFieldArrayValues);
1429
- registerFieldArray(prependValue);
1430
- focusNameRef.current = getFocusDetail(0, options);
1431
- };
1432
- const remove = (index) => {
1433
- const updatedFieldArrayValues = removeArrayAt(getCurrentFieldsValues(), index);
1434
- resetFields(index);
1435
- setFieldsAndNotify(updatedFieldArrayValues);
1436
- batchStateUpdate(removeArrayAt, {
1437
- argA: index,
1438
- }, updatedFieldArrayValues);
1439
- };
1440
- const insert$1 = (index, value, options) => {
1441
- const insertValue = Array.isArray(value) ? value : [value];
1442
- const updatedFieldArrayValues = insert(getCurrentFieldsValues(), index, insertValue);
1443
- setFieldsAndNotify(updatedFieldArrayValues);
1444
- batchStateUpdate(insert, {
1445
- argA: index,
1446
- argB: fillEmptyArray(value),
1447
- }, updatedFieldArrayValues);
1448
- registerFieldArray(insertValue, index);
1449
- focusNameRef.current = getFocusDetail(index, options);
1450
- };
1451
- const swap = (indexA, indexB) => {
1452
- const fieldValues = getCurrentFieldsValues();
1453
- swapArrayAt(fieldValues, indexA, indexB);
1454
- batchStateUpdate(swapArrayAt, {
1455
- argA: indexA,
1456
- argB: indexB,
1457
- }, fieldValues, false);
1458
- setFieldsAndNotify(fieldValues);
1459
- };
1460
- const move = (from, to) => {
1461
- const fieldValues = getCurrentFieldsValues();
1462
- moveArrayAt(fieldValues, from, to);
1463
- setFieldsAndNotify(fieldValues);
1464
- batchStateUpdate(moveArrayAt, {
1465
- argA: from,
1466
- argB: to,
1467
- }, fieldValues, false);
1468
- };
1469
- React__namespace.useEffect(() => {
1470
- if (isWatchAllRef.current) {
1471
- formStateSubjectRef.current.next({});
1506
+ onInvalid && (await onInvalid(formStateRef.current.errors, e));
1507
+ shouldFocusError &&
1508
+ focusFieldBy(fieldsRef.current, (key) => get(formStateRef.current.errors, key), fieldsNamesRef.current);
1509
+ }
1472
1510
  }
1473
- else {
1474
- for (const watchField of watchFieldsRef.current) {
1475
- if (name.startsWith(watchField)) {
1476
- formStateSubjectRef.current.next({});
1477
- break;
1511
+ finally {
1512
+ formStateRef.current.isSubmitted = true;
1513
+ formStateSubjectRef.current.next({
1514
+ isSubmitted: true,
1515
+ isSubmitting: false,
1516
+ isSubmitSuccessful: isEmptyObject(formStateRef.current.errors),
1517
+ submitCount: formStateRef.current.submitCount + 1,
1518
+ errors: formStateRef.current.errors,
1519
+ });
1520
+ }
1521
+ }, [shouldFocusError, isValidateAllFieldCriteria, criteriaMode]);
1522
+ const resetFromState = React__namespace.useCallback(({ keepErrors, keepDirty, keepIsSubmitted, keepTouched, keepIsValid, keepSubmitCount, }) => {
1523
+ if (!keepIsValid) {
1524
+ validFieldsRef.current = {};
1525
+ fieldsWithValidationRef.current = {};
1526
+ }
1527
+ watchFieldsRef.current = new Set();
1528
+ isWatchAllRef.current = false;
1529
+ formStateSubjectRef.current.next({
1530
+ submitCount: keepSubmitCount ? formStateRef.current.submitCount : 0,
1531
+ isDirty: keepDirty ? formStateRef.current.isDirty : false,
1532
+ isSubmitted: keepIsSubmitted ? formStateRef.current.isSubmitted : false,
1533
+ isValid: keepIsValid
1534
+ ? formStateRef.current.isValid
1535
+ : !validationMode.isOnSubmit,
1536
+ dirtyFields: keepDirty ? formStateRef.current.dirtyFields : {},
1537
+ touchedFields: keepTouched ? formStateRef.current.touchedFields : {},
1538
+ errors: keepErrors ? formStateRef.current.errors : {},
1539
+ isSubmitting: false,
1540
+ isSubmitSuccessful: false,
1541
+ });
1542
+ }, []);
1543
+ const reset = (values, keepStateOptions = {}) => {
1544
+ const updatedValues = values || defaultValuesRef.current;
1545
+ if (isWeb && !keepStateOptions.keepValues) {
1546
+ for (const field of Object.values(fieldsRef.current)) {
1547
+ if (field && field._f) {
1548
+ const inputRef = Array.isArray(field._f.refs)
1549
+ ? field._f.refs[0]
1550
+ : field._f.ref;
1551
+ if (isHTMLElement(inputRef)) {
1552
+ try {
1553
+ inputRef.closest('form').reset();
1554
+ break;
1555
+ }
1556
+ catch (_a) { }
1557
+ }
1478
1558
  }
1479
1559
  }
1480
1560
  }
1481
- watchSubjectRef.current.next({
1482
- name,
1483
- value: get(getFieldsValues(fieldsRef, defaultValuesRef), name, []),
1484
- });
1485
- focusNameRef.current &&
1486
- focusFieldBy(fieldsRef.current, (key) => key.startsWith(focusNameRef.current));
1487
- focusNameRef.current = '';
1488
- fieldArraySubjectRef.current.next({
1489
- name,
1490
- fields: omitKey([...fields]),
1491
- });
1492
- }, [fields, name]);
1561
+ !keepStateOptions.keepDefaultValues &&
1562
+ (defaultValuesRef.current = Object.assign({}, updatedValues));
1563
+ if (!keepStateOptions.keepValues) {
1564
+ fieldsRef.current = {};
1565
+ controllerSubjectRef.current.next({
1566
+ values: Object.assign({}, updatedValues),
1567
+ });
1568
+ watchSubjectRef.current.next({
1569
+ value: Object.assign({}, updatedValues),
1570
+ });
1571
+ fieldArraySubjectRef.current.next({
1572
+ fields: Object.assign({}, updatedValues),
1573
+ isReset: true,
1574
+ });
1575
+ }
1576
+ resetFromState(keepStateOptions);
1577
+ };
1493
1578
  React__namespace.useEffect(() => {
1494
- const fieldArraySubscription = fieldArraySubjectRef.current.subscribe({
1495
- next({ name: inputFieldArrayName, fields, isReset }) {
1496
- if (isReset) {
1497
- unset(fieldsRef.current, inputFieldArrayName || name);
1498
- inputFieldArrayName
1499
- ? set(fieldArrayDefaultValuesRef.current, inputFieldArrayName, fields)
1500
- : (fieldArrayDefaultValuesRef.current = fields);
1501
- setFieldsAndNotify(get(fieldArrayDefaultValuesRef.current, name));
1579
+ isMountedRef.current = true;
1580
+ const formStateSubscription = formStateSubjectRef.current.subscribe({
1581
+ next(formState = {}) {
1582
+ if (shouldRenderFormState(formState, readFormStateRef.current, true)) {
1583
+ formStateRef.current = Object.assign(Object.assign({}, formStateRef.current), formState);
1584
+ setFormState(formStateRef.current);
1502
1585
  }
1503
1586
  },
1504
1587
  });
1505
- !get(fieldsRef.current, name) && set(fieldsRef.current, name, []);
1506
- return () => {
1507
- fieldArrayDefaultValuesRef.current = getFieldsValues(fieldsRef);
1508
- fieldArraySubscription.unsubscribe();
1509
- };
1510
- }, []);
1511
- return {
1512
- swap: React__namespace.useCallback(swap, [name]),
1513
- move: React__namespace.useCallback(move, [name]),
1514
- prepend: React__namespace.useCallback(prepend$1, [name]),
1515
- append: React__namespace.useCallback(append$1, [name]),
1516
- remove: React__namespace.useCallback(remove, [name]),
1517
- insert: React__namespace.useCallback(insert$1, [name]),
1518
- fields: fields,
1519
- };
1520
- };
1521
-
1522
- function useFormState({ control, } = {}) {
1523
- const methods = useFormContext();
1524
- const { formStateRef, formStateSubjectRef, readFormStateRef } = control || methods.control;
1525
- const [formState, updateFormState] = React__namespace.useState(formStateRef.current);
1526
- const readFormState = React__namespace.useRef({
1527
- isDirty: false,
1528
- dirtyFields: false,
1529
- touchedFields: false,
1530
- isValidating: false,
1531
- isValid: false,
1532
- errors: false,
1533
- });
1534
- React__namespace.useEffect(() => {
1535
- const formStateSubscription = formStateSubjectRef.current.subscribe({
1536
- next: (formState) => {
1537
- shouldRenderFormState(formState, readFormState.current) &&
1538
- updateFormState(Object.assign(Object.assign({}, formStateRef.current), formState));
1588
+ const useFieldArraySubscription = fieldArraySubjectRef.current.subscribe({
1589
+ next(state) {
1590
+ if (state.fields && state.name && readFormStateRef.current.isValid) {
1591
+ const values = getFieldsValues(fieldsRef);
1592
+ set(values, state.name, state.fields);
1593
+ updateIsValid(values);
1594
+ }
1539
1595
  },
1540
1596
  });
1541
- return () => formStateSubscription.unsubscribe();
1597
+ resolverRef.current && readFormStateRef.current.isValid && updateIsValid();
1598
+ return () => {
1599
+ watchSubjectRef.current.unsubscribe();
1600
+ formStateSubscription.unsubscribe();
1601
+ useFieldArraySubscription.unsubscribe();
1602
+ };
1542
1603
  }, []);
1543
- return getProxyFormState(isProxyEnabled, formState, readFormStateRef, readFormState, false);
1544
- }
1545
-
1546
- var getControllerValue = (event) => isObject(event) && event.target
1547
- ? isCheckBoxInput(event.target)
1548
- ? event.target.checked
1549
- : event.target.value
1550
- : event;
1551
-
1552
- var isNameInFieldArray = (names, name) => [...names].some((current) => getNodeParentName(name) === current);
1553
-
1554
- function useController({ name, rules, defaultValue, control, }) {
1555
- const methods = useFormContext();
1556
- const { defaultValuesRef, register, fieldsRef, fieldArrayNamesRef, controllerSubjectRef, } = control || methods.control;
1557
- const { onChange, onBlur, ref } = register(name, rules);
1558
- const [value, setInputStateValue] = React__namespace.useState(isUndefined(get(fieldsRef.current, name)._f.value) ||
1559
- isNameInFieldArray(fieldArrayNamesRef.current, name)
1560
- ? isUndefined(defaultValue)
1561
- ? get(defaultValuesRef.current, name)
1562
- : defaultValue
1563
- : get(fieldsRef.current, name)._f.value);
1564
- const formState = useFormState({
1565
- control: control || methods.control,
1566
- });
1567
- get(fieldsRef.current, name)._f.value = value;
1568
- React__namespace.useEffect(() => {
1569
- const controllerSubscription = controllerSubjectRef.current.subscribe({
1570
- next: (data) => (!data.name || name === data.name) &&
1571
- setInputStateValue(get(data.values, name)),
1572
- });
1573
- return () => controllerSubscription.unsubscribe();
1574
- }, [name]);
1575
1604
  return {
1576
- field: {
1577
- onChange: (event) => {
1578
- const value = getControllerValue(event);
1579
- setInputStateValue(value);
1580
- onChange({
1581
- target: {
1582
- value,
1583
- name: name,
1584
- },
1585
- type: EVENTS.CHANGE,
1586
- });
1587
- },
1588
- onBlur: () => {
1589
- onBlur({
1590
- target: {
1591
- name: name,
1592
- },
1593
- type: EVENTS.BLUR,
1594
- });
1595
- },
1596
- name,
1597
- value,
1598
- ref,
1599
- },
1600
- formState,
1601
- fieldState: Object.defineProperties({}, {
1602
- invalid: {
1603
- get() {
1604
- return !!get(formState.errors, name);
1605
- },
1606
- },
1607
- isDirty: {
1608
- get() {
1609
- return !!get(formState.dirtyFields, name);
1610
- },
1611
- },
1612
- isTouched: {
1613
- get() {
1614
- return !!get(formState.touchedFields, name);
1615
- },
1616
- },
1617
- error: {
1618
- get() {
1619
- return get(formState.errors, name);
1620
- },
1621
- },
1622
- }),
1605
+ control: React__namespace.useMemo(() => ({
1606
+ register,
1607
+ isWatchAllRef,
1608
+ watchFieldsRef,
1609
+ getFormIsDirty,
1610
+ formStateSubjectRef,
1611
+ fieldArraySubjectRef,
1612
+ controllerSubjectRef,
1613
+ watchSubjectRef,
1614
+ watchInternal,
1615
+ fieldsRef,
1616
+ validFieldsRef,
1617
+ fieldsWithValidationRef,
1618
+ fieldArrayNamesRef,
1619
+ readFormStateRef,
1620
+ formStateRef,
1621
+ defaultValuesRef,
1622
+ fieldArrayDefaultValuesRef,
1623
+ }), []),
1624
+ formState: getProxyFormState(isProxyEnabled, formState, readFormStateRef),
1625
+ trigger,
1626
+ register,
1627
+ handleSubmit,
1628
+ watch: React__namespace.useCallback(watch, []),
1629
+ setValue: React__namespace.useCallback(setValue, [setInternalValues]),
1630
+ getValues: React__namespace.useCallback(getValues, []),
1631
+ reset: React__namespace.useCallback(reset, []),
1632
+ clearErrors: React__namespace.useCallback(clearErrors, []),
1633
+ unregister: React__namespace.useCallback(unregister, []),
1634
+ setError: React__namespace.useCallback(setError, []),
1623
1635
  };
1624
1636
  }
1625
1637
 
@@ -1649,8 +1661,6 @@ function useWatch(props) {
1649
1661
  return value;
1650
1662
  }
1651
1663
 
1652
- const Controller = (props) => props.render(useController(props));
1653
-
1654
1664
  exports.Controller = Controller;
1655
1665
  exports.FormProvider = FormProvider;
1656
1666
  exports.appendErrors = appendErrors;