@gorgo/medusa-integration 0.2.0 → 0.3.0-beta.1

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.
@@ -320,55 +320,45 @@ const IntegrationFieldValue = ({
320
320
  return /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", leading: "compact", children: String(value) });
321
321
  };
322
322
  var isCheckBoxInput = (element) => element.type === "checkbox";
323
+ var isFileInput = (element) => element.type === "file";
323
324
  var isDateObject = (value) => value instanceof Date;
324
325
  var isNullOrUndefined = (value) => value == null;
325
326
  const isObjectType = (value) => typeof value === "object";
326
327
  var isObject = (value) => !isNullOrUndefined(value) && !Array.isArray(value) && isObjectType(value) && !isDateObject(value);
327
- var getEventValue = (event) => isObject(event) && event.target ? isCheckBoxInput(event.target) ? event.target.checked : event.target.value : event;
328
- var getNodeParentName = (name) => name.substring(0, name.search(/\.\d+(\.|$)/)) || name;
329
- var isNameInFieldArray = (names, name) => names.has(getNodeParentName(name));
328
+ var getEventValue = (event) => isObject(event) && event.target ? isCheckBoxInput(event.target) ? event.target.checked : isFileInput(event.target) ? event.target.files : event.target.value : event;
329
+ var isNameInFieldArray = (names, name) => name.split(".").some((part, index, arr) => !isNaN(Number(part)) && names.has(arr.slice(0, index).join(".")));
330
330
  var isPlainObject = (tempObject) => {
331
331
  const prototypeCopy = tempObject.constructor && tempObject.constructor.prototype;
332
332
  return isObject(prototypeCopy) && prototypeCopy.hasOwnProperty("isPrototypeOf");
333
333
  };
334
334
  var isWeb = typeof window !== "undefined" && typeof window.HTMLElement !== "undefined" && typeof document !== "undefined";
335
335
  function cloneObject(data) {
336
- let copy;
337
- const isArray = Array.isArray(data);
338
336
  if (data instanceof Date) {
339
- copy = new Date(data);
340
- } else if (data instanceof Set) {
341
- copy = new Set(data);
342
- } else if (!(isWeb && (data instanceof Blob || data instanceof FileList)) && (isArray || isObject(data))) {
343
- copy = isArray ? [] : {};
344
- if (!isArray && !isPlainObject(data)) {
345
- copy = data;
346
- } else {
347
- for (const key in data) {
348
- if (data.hasOwnProperty(key)) {
349
- copy[key] = cloneObject(data[key]);
350
- }
351
- }
352
- }
353
- } else {
337
+ return new Date(data);
338
+ }
339
+ const isFileListInstance = typeof FileList !== "undefined" && data instanceof FileList;
340
+ if (isWeb && (data instanceof Blob || isFileListInstance)) {
354
341
  return data;
355
342
  }
343
+ const isArray = Array.isArray(data);
344
+ if (!isArray && !(isObject(data) && isPlainObject(data))) {
345
+ return data;
346
+ }
347
+ const copy = isArray ? [] : Object.create(Object.getPrototypeOf(data));
348
+ for (const key in data) {
349
+ if (Object.prototype.hasOwnProperty.call(data, key)) {
350
+ copy[key] = cloneObject(data[key]);
351
+ }
352
+ }
356
353
  return copy;
357
354
  }
358
- var compact = (value) => Array.isArray(value) ? value.filter(Boolean) : [];
359
- var isUndefined = (val) => val === void 0;
360
- var get = (object, path, defaultValue) => {
361
- if (!path || !isObject(object)) {
362
- return defaultValue;
363
- }
364
- const result = compact(path.split(/[,[\].]+?/)).reduce((result2, key) => isNullOrUndefined(result2) ? result2 : result2[key], object);
365
- return isUndefined(result) || result === object ? isUndefined(object[path]) ? defaultValue : object[path] : result;
366
- };
367
- var isBoolean = (value) => typeof value === "boolean";
368
355
  const EVENTS = {
369
356
  BLUR: "blur",
370
357
  FOCUS_OUT: "focusout",
371
- CHANGE: "change"
358
+ CHANGE: "change",
359
+ SUBMIT: "submit",
360
+ TRIGGER: "trigger",
361
+ VALID: "valid"
372
362
  };
373
363
  const VALIDATION_MODE = {
374
364
  onBlur: "onBlur",
@@ -386,12 +376,52 @@ const INPUT_VALIDATION_RULES = {
386
376
  required: "required",
387
377
  validate: "validate"
388
378
  };
389
- const HookFormContext = React__default.default.createContext(null);
390
- const useFormContext = () => React__default.default.useContext(HookFormContext);
379
+ const ROOT_ERROR_TYPE = "root";
380
+ const PROTOTYPE_KEYWORDS = ["__proto__", "constructor", "prototype"];
381
+ const IS_KEY_RE = /^\w*$/;
382
+ var isKey = (value) => IS_KEY_RE.test(value);
383
+ var isUndefined = (val) => val === void 0;
384
+ const FIELD_PATH_RE = /[.[\]'"]/;
385
+ var stringToPath = (input) => input.split(FIELD_PATH_RE).filter(Boolean);
386
+ var get = (object, path, defaultValue) => {
387
+ if (!path || !isObject(object)) {
388
+ return defaultValue;
389
+ }
390
+ const paths = isKey(path) ? [path] : stringToPath(path);
391
+ if (paths.some((key) => PROTOTYPE_KEYWORDS.includes(key))) {
392
+ return defaultValue;
393
+ }
394
+ const result = paths.reduce((result2, key) => {
395
+ return isNullOrUndefined(result2) ? void 0 : result2[key];
396
+ }, object);
397
+ return isUndefined(result) || result === object ? isUndefined(object[path]) ? defaultValue : object[path] : result;
398
+ };
399
+ var isBoolean = (value) => typeof value === "boolean";
400
+ var isFunction = (value) => typeof value === "function";
401
+ var set = (object, path, value) => {
402
+ let index = -1;
403
+ const tempPath = isKey(path) ? [path] : stringToPath(path);
404
+ const length = tempPath.length;
405
+ const lastIndex = length - 1;
406
+ while (++index < length) {
407
+ const key = tempPath[index];
408
+ let newValue = value;
409
+ if (index !== lastIndex) {
410
+ const objValue = object[key];
411
+ newValue = isObject(objValue) || Array.isArray(objValue) ? objValue : !isNaN(+tempPath[index + 1]) ? [] : {};
412
+ }
413
+ if (PROTOTYPE_KEYWORDS.includes(key)) {
414
+ return;
415
+ }
416
+ object[key] = newValue;
417
+ object = object[key];
418
+ }
419
+ };
420
+ const HookFormControlContext = React__default.default.createContext(null);
421
+ HookFormControlContext.displayName = "HookFormControlContext";
422
+ const useFormControlContext = () => React__default.default.useContext(HookFormControlContext);
391
423
  var getProxyFormState = (formState, control, localProxyFormState, isRoot = true) => {
392
- const result = {
393
- defaultValues: control._defaultValues
394
- };
424
+ const result = {};
395
425
  for (const key in formState) {
396
426
  Object.defineProperty(result, key, {
397
427
  get: () => {
@@ -406,58 +436,40 @@ var getProxyFormState = (formState, control, localProxyFormState, isRoot = true)
406
436
  }
407
437
  return result;
408
438
  };
409
- var isEmptyObject = (value) => isObject(value) && !Object.keys(value).length;
410
- var shouldRenderFormState = (formStateData, _proxyFormState, updateFormState, isRoot) => {
411
- updateFormState(formStateData);
412
- const { name, ...formState } = formStateData;
413
- return isEmptyObject(formState) || Object.keys(formState).length >= Object.keys(_proxyFormState).length || Object.keys(formState).find((key) => _proxyFormState[key] === (!isRoot || VALIDATION_MODE.all));
414
- };
415
- var convertToArrayPayload = (value) => Array.isArray(value) ? value : [value];
416
- var shouldSubscribeByName = (name, signalName, exact) => !name || !signalName || name === signalName || convertToArrayPayload(name).some((currentName) => currentName && (exact ? currentName === signalName : currentName.startsWith(signalName) || signalName.startsWith(currentName)));
417
- function useSubscribe(props) {
418
- const _props = React__default.default.useRef(props);
419
- _props.current = props;
420
- React__default.default.useEffect(() => {
421
- const subscription = !props.disabled && _props.current.subject && _props.current.subject.subscribe({
422
- next: _props.current.next
423
- });
424
- return () => {
425
- subscription && subscription.unsubscribe();
426
- };
427
- }, [props.disabled]);
428
- }
439
+ const useIsomorphicLayoutEffect = isWeb ? React__default.default.useLayoutEffect : React__default.default.useEffect;
429
440
  function useFormState(props) {
430
- const methods = useFormContext();
431
- const { control = methods.control, disabled, name, exact } = props || {};
432
- const [formState, updateFormState] = React__default.default.useState(control._formState);
433
- const _mounted = React__default.default.useRef(true);
441
+ const formControl = useFormControlContext();
442
+ const { control = formControl, disabled, name, exact } = props || {};
443
+ const [formState, updateFormState] = React__default.default.useState(() => ({
444
+ ...control._formState,
445
+ defaultValues: control._defaultValues
446
+ }));
434
447
  const _localProxyFormState = React__default.default.useRef({
435
448
  isDirty: false,
436
449
  isLoading: false,
437
450
  dirtyFields: false,
438
451
  touchedFields: false,
452
+ validatingFields: false,
439
453
  isValidating: false,
440
454
  isValid: false,
441
455
  errors: false
442
456
  });
443
- const _name = React__default.default.useRef(name);
444
- _name.current = name;
445
- useSubscribe({
446
- disabled,
447
- next: (value) => _mounted.current && shouldSubscribeByName(_name.current, value.name, exact) && shouldRenderFormState(value, _localProxyFormState.current, control._updateFormState) && updateFormState({
448
- ...control._formState,
449
- ...value
450
- }),
451
- subject: control._subjects.state
452
- });
457
+ useIsomorphicLayoutEffect(() => control._subscribe({
458
+ name,
459
+ formState: _localProxyFormState.current,
460
+ exact,
461
+ callback: (formState2) => {
462
+ !disabled && updateFormState({
463
+ ...control._formState,
464
+ ...formState2,
465
+ defaultValues: control._defaultValues
466
+ });
467
+ }
468
+ }), [name, disabled, exact]);
453
469
  React__default.default.useEffect(() => {
454
- _mounted.current = true;
455
- _localProxyFormState.current.isValid && control._updateValid(true);
456
- return () => {
457
- _mounted.current = false;
458
- };
470
+ _localProxyFormState.current.isValid && control._setValid(true);
459
471
  }, [control]);
460
- return getProxyFormState(formState, control, _localProxyFormState.current, false);
472
+ return React__default.default.useMemo(() => getProxyFormState(formState, control, _localProxyFormState.current, false), [formState, control]);
461
473
  }
462
474
  var isString = (value) => typeof value === "string";
463
475
  var generateWatchOutput = (names, _names, formValues, isGlobal, defaultValue) => {
@@ -471,152 +483,250 @@ var generateWatchOutput = (names, _names, formValues, isGlobal, defaultValue) =>
471
483
  isGlobal && (_names.watchAll = true);
472
484
  return formValues;
473
485
  };
474
- function useWatch(props) {
475
- const methods = useFormContext();
476
- const { control = methods.control, name, defaultValue, disabled, exact } = props || {};
477
- const _name = React__default.default.useRef(name);
478
- _name.current = name;
479
- useSubscribe({
480
- disabled,
481
- subject: control._subjects.values,
482
- next: (formState) => {
483
- if (shouldSubscribeByName(_name.current, formState.name, exact)) {
484
- updateValue(cloneObject(generateWatchOutput(_name.current, control._names, formState.values || control._formValues, false, defaultValue)));
486
+ var isPrimitive = (value) => isNullOrUndefined(value) || !isObjectType(value);
487
+ const isEmptyObjectWithCustomPrototype = (object, keys) => keys.length === 0 && !Array.isArray(object) && !isPlainObject(object);
488
+ function deepEqual(object1, object2, visited = /* @__PURE__ */ new WeakMap()) {
489
+ if (object1 === object2) {
490
+ return true;
491
+ }
492
+ if (isPrimitive(object1) || isPrimitive(object2)) {
493
+ return Object.is(object1, object2);
494
+ }
495
+ if (isDateObject(object1) && isDateObject(object2)) {
496
+ return Object.is(object1.getTime(), object2.getTime());
497
+ }
498
+ const keys1 = Object.keys(object1);
499
+ const keys2 = Object.keys(object2);
500
+ if (keys1.length !== keys2.length) {
501
+ return false;
502
+ }
503
+ if (isEmptyObjectWithCustomPrototype(object1, keys1) || isEmptyObjectWithCustomPrototype(object2, keys2)) {
504
+ return Object.is(object1, object2);
505
+ }
506
+ if (!keys1.length && Array.isArray(object1) !== Array.isArray(object2)) {
507
+ return false;
508
+ }
509
+ const visitedPairs = visited.get(object1);
510
+ if (visitedPairs && visitedPairs.has(object2)) {
511
+ return true;
512
+ }
513
+ if (visitedPairs) {
514
+ visitedPairs.add(object2);
515
+ } else {
516
+ const ws = /* @__PURE__ */ new WeakSet();
517
+ ws.add(object2);
518
+ visited.set(object1, ws);
519
+ }
520
+ for (const key of keys1) {
521
+ const val1 = object1[key];
522
+ if (!(key in object2)) {
523
+ return false;
524
+ }
525
+ if (key !== "ref") {
526
+ const val2 = object2[key];
527
+ if (isDateObject(val1) && isDateObject(val2) || (isObject(val1) || Array.isArray(val1)) && (isObject(val2) || Array.isArray(val2)) ? !deepEqual(val1, val2, visited) : !Object.is(val1, val2)) {
528
+ return false;
485
529
  }
486
530
  }
531
+ }
532
+ return true;
533
+ }
534
+ function useWatch(props) {
535
+ const formControl = useFormControlContext();
536
+ const { control = formControl, name, defaultValue, disabled, exact, compute } = props || {};
537
+ const _defaultValue = React__default.default.useRef(defaultValue);
538
+ const _compute = React__default.default.useRef(compute);
539
+ const _computeFormValues = React__default.default.useRef(void 0);
540
+ const _prevControl = React__default.default.useRef(control);
541
+ const _prevName = React__default.default.useRef(name);
542
+ _compute.current = compute;
543
+ const [value, updateValue] = React__default.default.useState(() => {
544
+ const defaultValue2 = control._getWatch(name, _defaultValue.current);
545
+ return _compute.current ? _compute.current(defaultValue2) : defaultValue2;
487
546
  });
488
- const [value, updateValue] = React__default.default.useState(control._getWatch(name, defaultValue));
547
+ const getCurrentOutput = React__default.default.useCallback((values) => {
548
+ const formValues = generateWatchOutput(name, control._names, values || control._formValues, false, _defaultValue.current);
549
+ return _compute.current ? _compute.current(formValues) : formValues;
550
+ }, [control._formValues, control._names, name]);
551
+ const refreshValue = React__default.default.useCallback((values) => {
552
+ if (!disabled) {
553
+ const formValues = generateWatchOutput(name, control._names, values || control._formValues, false, _defaultValue.current);
554
+ if (_compute.current) {
555
+ const computedFormValues = _compute.current(formValues);
556
+ if (!deepEqual(computedFormValues, _computeFormValues.current)) {
557
+ updateValue(computedFormValues);
558
+ _computeFormValues.current = computedFormValues;
559
+ }
560
+ } else {
561
+ updateValue(formValues);
562
+ }
563
+ }
564
+ }, [control._formValues, control._names, disabled, name]);
565
+ useIsomorphicLayoutEffect(() => {
566
+ if (_prevControl.current !== control || !deepEqual(_prevName.current, name)) {
567
+ _prevControl.current = control;
568
+ _prevName.current = name;
569
+ refreshValue();
570
+ }
571
+ return control._subscribe({
572
+ name,
573
+ formState: {
574
+ values: true
575
+ },
576
+ exact,
577
+ callback: (formState) => {
578
+ refreshValue(formState.values);
579
+ }
580
+ });
581
+ }, [control, exact, name, refreshValue]);
489
582
  React__default.default.useEffect(() => control._removeUnmounted());
490
- return value;
583
+ const controlChanged = _prevControl.current !== control;
584
+ const prevName = _prevName.current;
585
+ const computedOutput = React__default.default.useMemo(() => {
586
+ if (disabled) {
587
+ return null;
588
+ }
589
+ const nameChanged = !controlChanged && !deepEqual(prevName, name);
590
+ const shouldReturnImmediate = controlChanged || nameChanged;
591
+ return shouldReturnImmediate ? getCurrentOutput() : null;
592
+ }, [disabled, controlChanged, name, prevName, getCurrentOutput]);
593
+ return computedOutput !== null ? computedOutput : value;
491
594
  }
492
- var isKey = (value) => /^\w*$/.test(value);
493
- var stringToPath = (input) => compact(input.replace(/["|']|\]/g, "").split(/\.|\[/));
494
- var set = (object, path, value) => {
495
- let index = -1;
496
- const tempPath = isKey(path) ? [path] : stringToPath(path);
497
- const length = tempPath.length;
498
- const lastIndex = length - 1;
499
- while (++index < length) {
500
- const key = tempPath[index];
501
- let newValue = value;
502
- if (index !== lastIndex) {
503
- const objValue = object[key];
504
- newValue = isObject(objValue) || Array.isArray(objValue) ? objValue : !isNaN(+tempPath[index + 1]) ? [] : {};
505
- }
506
- object[key] = newValue;
507
- object = object[key];
508
- }
509
- return object;
510
- };
511
595
  function useController(props) {
512
- const methods = useFormContext();
513
- const { name, disabled, control = methods.control, shouldUnregister } = props;
596
+ const formControl = useFormControlContext();
597
+ const { name, disabled, control = formControl, shouldUnregister, defaultValue, exact = true } = props;
514
598
  const isArrayField = isNameInFieldArray(control._names.array, name);
599
+ const defaultValueMemo = React__default.default.useMemo(() => get(control._formValues, name, get(control._defaultValues, name, defaultValue)), [control, name, defaultValue]);
515
600
  const value = useWatch({
516
601
  control,
517
602
  name,
518
- defaultValue: get(control._formValues, name, get(control._defaultValues, name, props.defaultValue)),
519
- exact: true
603
+ defaultValue: defaultValueMemo,
604
+ exact
520
605
  });
521
606
  const formState = useFormState({
522
607
  control,
523
- name
608
+ name,
609
+ exact
524
610
  });
611
+ const _props = React__default.default.useRef(props);
612
+ const _proxyRef = React__default.default.useRef(null);
525
613
  const _registerProps = React__default.default.useRef(control.register(name, {
526
614
  ...props.rules,
527
615
  value,
528
616
  ...isBoolean(props.disabled) ? { disabled: props.disabled } : {}
529
617
  }));
618
+ _props.current = props;
619
+ const fieldState = React__default.default.useMemo(() => Object.defineProperties({}, {
620
+ invalid: {
621
+ enumerable: true,
622
+ get: () => !!get(formState.errors, name)
623
+ },
624
+ isDirty: {
625
+ enumerable: true,
626
+ get: () => !!get(formState.dirtyFields, name)
627
+ },
628
+ isTouched: {
629
+ enumerable: true,
630
+ get: () => !!get(formState.touchedFields, name)
631
+ },
632
+ isValidating: {
633
+ enumerable: true,
634
+ get: () => !!get(formState.validatingFields, name)
635
+ },
636
+ error: {
637
+ enumerable: true,
638
+ get: () => get(formState.errors, name)
639
+ }
640
+ }), [formState, name]);
641
+ const onChange = React__default.default.useCallback((event) => {
642
+ const value2 = getEventValue(event);
643
+ if (!get(control._fields, name)) {
644
+ _registerProps.current = control.register(name, {
645
+ ..._props.current.rules,
646
+ value: value2
647
+ });
648
+ }
649
+ return _registerProps.current.onChange({
650
+ target: {
651
+ value: getEventValue(event),
652
+ name
653
+ },
654
+ type: EVENTS.CHANGE
655
+ });
656
+ }, [name, control]);
657
+ const onBlur = React__default.default.useCallback(() => _registerProps.current.onBlur({
658
+ target: {
659
+ value: get(control._formValues, name),
660
+ name
661
+ },
662
+ type: EVENTS.BLUR
663
+ }), [name, control._formValues]);
664
+ const ref = React__default.default.useCallback((elm) => {
665
+ if (elm) {
666
+ _proxyRef.current = {
667
+ focus: () => isFunction(elm.focus) && elm.focus(),
668
+ select: () => isFunction(elm.select) && elm.select(),
669
+ setCustomValidity: (message) => isFunction(elm.setCustomValidity) && elm.setCustomValidity(message),
670
+ reportValidity: () => isFunction(elm.reportValidity) && elm.reportValidity()
671
+ };
672
+ }
673
+ const field2 = get(control._fields, name);
674
+ if (field2 && field2._f && elm) {
675
+ field2._f.ref = _proxyRef.current;
676
+ }
677
+ }, [control._fields, name]);
678
+ const field = React__default.default.useMemo(() => ({
679
+ name,
680
+ value,
681
+ ...isBoolean(disabled) || formState.disabled ? { disabled: formState.disabled || disabled } : {},
682
+ onChange,
683
+ onBlur,
684
+ ref
685
+ }), [name, disabled, formState.disabled, onChange, onBlur, ref, value]);
530
686
  React__default.default.useEffect(() => {
531
687
  const _shouldUnregisterField = control._options.shouldUnregister || shouldUnregister;
688
+ _registerProps.current = control.register(name, {
689
+ ..._props.current.rules,
690
+ ...isBoolean(_props.current.disabled) ? { disabled: _props.current.disabled } : {}
691
+ });
532
692
  const updateMounted = (name2, value2) => {
533
- const field = get(control._fields, name2);
534
- if (field) {
535
- field._f.mount = value2;
693
+ const field2 = get(control._fields, name2);
694
+ if (field2 && field2._f) {
695
+ field2._f.mount = value2;
536
696
  }
537
697
  };
538
698
  updateMounted(name, true);
539
699
  if (_shouldUnregisterField) {
540
- const value2 = cloneObject(get(control._options.defaultValues, name));
700
+ const value2 = cloneObject(get(shouldUnregister ? control._defaultValues : control._options.values || control._defaultValues, name, get(control._options.defaultValues, name, _props.current.defaultValue)));
541
701
  set(control._defaultValues, name, value2);
542
702
  if (isUndefined(get(control._formValues, name))) {
543
703
  set(control._formValues, name, value2);
544
704
  }
545
705
  }
706
+ !isArrayField && control.register(name);
707
+ if (_proxyRef.current) {
708
+ const field2 = get(control._fields, name);
709
+ if (field2 && field2._f) {
710
+ field2._f.ref = _proxyRef.current;
711
+ }
712
+ }
546
713
  return () => {
547
714
  (isArrayField ? _shouldUnregisterField && !control._state.action : _shouldUnregisterField) ? control.unregister(name) : updateMounted(name, false);
548
715
  };
549
716
  }, [name, control, isArrayField, shouldUnregister]);
550
717
  React__default.default.useEffect(() => {
551
- if (get(control._fields, name)) {
552
- control._updateDisabledField({
553
- disabled,
554
- fields: control._fields,
555
- name,
556
- value: get(control._fields, name)._f.value
557
- });
558
- }
718
+ control._setDisabledField({
719
+ disabled,
720
+ name
721
+ });
559
722
  }, [disabled, name, control]);
560
- return {
561
- field: {
562
- name,
563
- value,
564
- ...isBoolean(disabled) || isBoolean(formState.disabled) ? { disabled: formState.disabled || disabled } : {},
565
- onChange: React__default.default.useCallback((event) => _registerProps.current.onChange({
566
- target: {
567
- value: getEventValue(event),
568
- name
569
- },
570
- type: EVENTS.CHANGE
571
- }), [name]),
572
- onBlur: React__default.default.useCallback(() => _registerProps.current.onBlur({
573
- target: {
574
- value: get(control._formValues, name),
575
- name
576
- },
577
- type: EVENTS.BLUR
578
- }), [name, control]),
579
- ref: (elm) => {
580
- const field = get(control._fields, name);
581
- if (field && elm) {
582
- field._f.ref = {
583
- focus: () => elm.focus(),
584
- select: () => elm.select(),
585
- setCustomValidity: (message) => elm.setCustomValidity(message),
586
- reportValidity: () => elm.reportValidity()
587
- };
588
- }
589
- }
590
- },
723
+ return React__default.default.useMemo(() => ({
724
+ field,
591
725
  formState,
592
- fieldState: Object.defineProperties({}, {
593
- invalid: {
594
- enumerable: true,
595
- get: () => !!get(formState.errors, name)
596
- },
597
- isDirty: {
598
- enumerable: true,
599
- get: () => !!get(formState.dirtyFields, name)
600
- },
601
- isTouched: {
602
- enumerable: true,
603
- get: () => !!get(formState.touchedFields, name)
604
- },
605
- error: {
606
- enumerable: true,
607
- get: () => get(formState.errors, name)
608
- }
609
- })
610
- };
726
+ fieldState
727
+ }), [field, formState, fieldState]);
611
728
  }
612
729
  const Controller = (props) => props.render(useController(props));
613
- var appendErrors = (name, validateAllFieldCriteria, errors, type, message) => validateAllFieldCriteria ? {
614
- ...errors[name],
615
- types: {
616
- ...errors[name] && errors[name].types ? errors[name].types : {},
617
- [type]: message || true
618
- }
619
- } : {};
620
730
  var getValidationModes = (mode) => ({
621
731
  isOnSubmit: !mode || mode === VALIDATION_MODE.onSubmit,
622
732
  isOnBlur: mode === VALIDATION_MODE.onBlur,
@@ -624,7 +734,17 @@ var getValidationModes = (mode) => ({
624
734
  isOnAll: mode === VALIDATION_MODE.all,
625
735
  isOnTouch: mode === VALIDATION_MODE.onTouched
626
736
  });
627
- var isWatched = (name, _names, isBlurEvent) => !isBlurEvent && (_names.watchAll || _names.watch.has(name) || [..._names.watch].some((watchName) => name.startsWith(watchName) && /^\.\w+/.test(name.slice(watchName.length))));
737
+ var isWatched = (name, _names, isBlurEvent) => {
738
+ if (isBlurEvent)
739
+ return false;
740
+ if (_names.watchAll || _names.watch.has(name))
741
+ return true;
742
+ for (const watchName of _names.watch) {
743
+ if (name.startsWith(watchName) && name.charAt(watchName.length) === ".")
744
+ return true;
745
+ }
746
+ return false;
747
+ };
628
748
  const iterateFieldsByAction = (fields, action, fieldsNames, abortEarly) => {
629
749
  for (const key of fieldsNames || Object.keys(fields)) {
630
750
  const field = get(fields, key);
@@ -632,26 +752,31 @@ const iterateFieldsByAction = (fields, action, fieldsNames, abortEarly) => {
632
752
  const { _f, ...currentField } = field;
633
753
  if (_f) {
634
754
  if (_f.refs && _f.refs[0] && action(_f.refs[0], key) && !abortEarly) {
635
- break;
755
+ return true;
636
756
  } else if (_f.ref && action(_f.ref, _f.name) && !abortEarly) {
637
- break;
757
+ return true;
638
758
  } else {
639
- iterateFieldsByAction(currentField, action);
759
+ if (iterateFieldsByAction(currentField, action)) {
760
+ break;
761
+ }
640
762
  }
641
763
  } else if (isObject(currentField)) {
642
- iterateFieldsByAction(currentField, action);
764
+ if (iterateFieldsByAction(currentField, action)) {
765
+ break;
766
+ }
643
767
  }
644
768
  }
645
769
  }
770
+ return;
646
771
  };
647
772
  var updateFieldArrayRootError = (errors, error, name) => {
648
- const fieldArrayErrors = compact(get(errors, name));
649
- set(fieldArrayErrors, "root", error[name]);
773
+ const existingErrors = get(errors, name);
774
+ const fieldArrayErrors = Array.isArray(existingErrors) ? existingErrors : [];
775
+ set(fieldArrayErrors, ROOT_ERROR_TYPE, error[name]);
650
776
  set(errors, name, fieldArrayErrors);
651
777
  return errors;
652
778
  };
653
- var isFileInput = (element) => element.type === "file";
654
- var isFunction = (value) => typeof value === "function";
779
+ var isEmptyObject = (value) => isObject(value) && !Object.keys(value).length;
655
780
  var isHTMLElement = (value) => {
656
781
  if (!isWeb) {
657
782
  return false;
@@ -659,9 +784,15 @@ var isHTMLElement = (value) => {
659
784
  const owner = value ? value.ownerDocument : 0;
660
785
  return value instanceof (owner && owner.defaultView ? owner.defaultView.HTMLElement : HTMLElement);
661
786
  };
662
- var isMessage = (value) => isString(value);
663
787
  var isRadioInput = (element) => element.type === "radio";
664
788
  var isRegex = (value) => value instanceof RegExp;
789
+ var appendErrors = (name, validateAllFieldCriteria, errors, type, message) => validateAllFieldCriteria ? {
790
+ ...errors[name],
791
+ types: {
792
+ ...errors[name] && errors[name].types ? errors[name].types : {},
793
+ [type]: message || true
794
+ }
795
+ } : {};
665
796
  const defaultResult = {
666
797
  value: false,
667
798
  isValid: false
@@ -689,10 +820,10 @@ var getRadioValue = (options) => Array.isArray(options) ? options.reduce((previo
689
820
  value: option.value
690
821
  } : previous, defaultReturn) : defaultReturn;
691
822
  function getValidateError(result, ref, type = "validate") {
692
- if (isMessage(result) || Array.isArray(result) && result.every(isMessage) || isBoolean(result) && !result) {
823
+ if (isString(result) || Array.isArray(result) && result.every(isString) || isBoolean(result) && !result) {
693
824
  return {
694
825
  type,
695
- message: isMessage(result) ? result : "",
826
+ message: isString(result) ? result : "",
696
827
  ref
697
828
  };
698
829
  }
@@ -701,16 +832,21 @@ var getValueAndMessage = (validationData) => isObject(validationData) && !isRege
701
832
  value: validationData,
702
833
  message: ""
703
834
  };
704
- var validateField = async (field, formValues, validateAllFieldCriteria, shouldUseNativeValidation, isFieldArray) => {
705
- const { ref, refs, required, maxLength, minLength, min, max, pattern, validate, name, valueAsNumber, mount, disabled } = field._f;
835
+ var validateField = async (field, disabledFieldNames, formValues, validateAllFieldCriteria, shouldUseNativeValidation, isFieldArray) => {
836
+ const { ref, refs, required, maxLength, minLength, min, max, pattern, validate, name, valueAsNumber, mount } = field._f;
706
837
  const inputValue = get(formValues, name);
707
- if (!mount || disabled) {
838
+ if (!mount || disabledFieldNames.has(name)) {
708
839
  return {};
709
840
  }
710
841
  const inputRef = refs ? refs[0] : ref;
711
842
  const setCustomValidity = (message) => {
712
843
  if (shouldUseNativeValidation && inputRef.reportValidity) {
713
- inputRef.setCustomValidity(isBoolean(message) ? "" : message || "");
844
+ const validityMessage = isBoolean(message) ? "" : message || "";
845
+ if (refs) {
846
+ refs.forEach((ref2) => ref2.setCustomValidity(validityMessage));
847
+ } else {
848
+ inputRef.setCustomValidity(validityMessage);
849
+ }
714
850
  inputRef.reportValidity();
715
851
  }
716
852
  };
@@ -730,7 +866,7 @@ var validateField = async (field, formValues, validateAllFieldCriteria, shouldUs
730
866
  };
731
867
  };
732
868
  if (isFieldArray ? !Array.isArray(inputValue) || !inputValue.length : required && (!isRadioOrCheckbox2 && (isEmpty || isNullOrUndefined(inputValue)) || isBoolean(inputValue) && !inputValue || isCheckBox && !getCheckboxValue(refs).isValid || isRadio && !getRadioValue(refs).isValid)) {
733
- const { value, message } = isMessage(required) ? { value: !!required, message: required } : getValueAndMessage(required);
869
+ const { value, message } = isString(required) ? { value: !!required, message: required } : getValueAndMessage(required);
734
870
  if (value) {
735
871
  error[name] = {
736
872
  type: INPUT_VALIDATION_RULES.required,
@@ -851,11 +987,18 @@ var validateField = async (field, formValues, validateAllFieldCriteria, shouldUs
851
987
  setCustomValidity(true);
852
988
  return error;
853
989
  };
990
+ var convertToArrayPayload = (value) => Array.isArray(value) ? value : [value];
991
+ var compact = (value) => Array.isArray(value) ? value.filter(Boolean) : [];
854
992
  function baseGet(object, updatePath) {
855
993
  const length = updatePath.slice(0, -1).length;
856
994
  let index = 0;
857
995
  while (index < length) {
858
- object = isUndefined(object) ? index++ : object[updatePath[index++]];
996
+ if (isNullOrUndefined(object)) {
997
+ object = void 0;
998
+ break;
999
+ }
1000
+ object = object[updatePath[index]];
1001
+ index++;
859
1002
  }
860
1003
  return object;
861
1004
  }
@@ -868,7 +1011,14 @@ function isEmptyArray(obj) {
868
1011
  return true;
869
1012
  }
870
1013
  function unset(object, path) {
1014
+ if (isString(path) && Object.prototype.hasOwnProperty.call(object, path)) {
1015
+ delete object[path];
1016
+ return object;
1017
+ }
871
1018
  const paths = Array.isArray(path) ? path : isKey(path) ? [path] : stringToPath(path);
1019
+ if (paths.some((segment) => PROTOTYPE_KEYWORDS.includes(String(segment)))) {
1020
+ return object;
1021
+ }
872
1022
  const childObject = paths.length === 1 ? object : baseGet(object, paths);
873
1023
  const index = paths.length - 1;
874
1024
  const key = paths[index];
@@ -880,6 +1030,22 @@ function unset(object, path) {
880
1030
  }
881
1031
  return object;
882
1032
  }
1033
+ const flatten = (obj) => {
1034
+ const output = {};
1035
+ for (const key of Object.keys(obj)) {
1036
+ if (isObjectType(obj[key]) && obj[key] !== null && !isDateObject(obj[key])) {
1037
+ const nested = flatten(obj[key]);
1038
+ for (const nestedKey of Object.keys(nested)) {
1039
+ output[`${key}.${nestedKey}`] = nested[nestedKey];
1040
+ }
1041
+ } else {
1042
+ output[key] = obj[key];
1043
+ }
1044
+ }
1045
+ return output;
1046
+ };
1047
+ const HookFormContext = React__default.default.createContext(null);
1048
+ HookFormContext.displayName = "HookFormContext";
883
1049
  var createSubject = () => {
884
1050
  let _observers = [];
885
1051
  const next = (value) => {
@@ -907,32 +1073,23 @@ var createSubject = () => {
907
1073
  unsubscribe
908
1074
  };
909
1075
  };
910
- var isPrimitive = (value) => isNullOrUndefined(value) || !isObjectType(value);
911
- function deepEqual(object1, object2) {
912
- if (isPrimitive(object1) || isPrimitive(object2)) {
913
- return object1 === object2;
914
- }
915
- if (isDateObject(object1) && isDateObject(object2)) {
916
- return object1.getTime() === object2.getTime();
917
- }
918
- const keys1 = Object.keys(object1);
919
- const keys2 = Object.keys(object2);
920
- if (keys1.length !== keys2.length) {
921
- return false;
922
- }
923
- for (const key of keys1) {
924
- const val1 = object1[key];
925
- if (!keys2.includes(key)) {
926
- return false;
927
- }
928
- if (key !== "ref") {
929
- const val2 = object2[key];
930
- if (isDateObject(val1) && isDateObject(val2) || isObject(val1) && isObject(val2) || Array.isArray(val1) && Array.isArray(val2) ? !deepEqual(val1, val2) : val1 !== val2) {
931
- return false;
1076
+ function extractFormValues(fieldsState, formValues) {
1077
+ const values = {};
1078
+ for (const key in fieldsState) {
1079
+ if (fieldsState.hasOwnProperty(key)) {
1080
+ const fieldState = fieldsState[key];
1081
+ const fieldValue = formValues[key];
1082
+ if (fieldState && isObject(fieldState) && fieldValue) {
1083
+ const nestedFieldsState = extractFormValues(fieldState, fieldValue);
1084
+ if (isObject(nestedFieldsState)) {
1085
+ values[key] = nestedFieldsState;
1086
+ }
1087
+ } else if (fieldsState[key]) {
1088
+ values[key] = fieldValue;
932
1089
  }
933
1090
  }
934
1091
  }
935
- return true;
1092
+ return values;
936
1093
  }
937
1094
  var isMultipleSelect = (element) => element.type === `select-multiple`;
938
1095
  var isRadioOrCheckbox = (ref) => isRadioInput(ref) || isCheckBoxInput(ref);
@@ -945,44 +1102,65 @@ var objectHasFunction = (data) => {
945
1102
  }
946
1103
  return false;
947
1104
  };
948
- function markFieldsDirty(data, fields = {}) {
949
- const isParentNodeArray = Array.isArray(data);
950
- if (isObject(data) || isParentNodeArray) {
951
- for (const key in data) {
952
- if (Array.isArray(data[key]) || isObject(data[key]) && !objectHasFunction(data[key])) {
953
- fields[key] = Array.isArray(data[key]) ? [] : {};
954
- markFieldsDirty(data[key], fields[key]);
955
- } else if (!isNullOrUndefined(data[key])) {
956
- fields[key] = true;
1105
+ function isTraversable(value) {
1106
+ return Array.isArray(value) || isObject(value) && !objectHasFunction(value);
1107
+ }
1108
+ function isRegisteredLeaf(fieldRef) {
1109
+ return !!(fieldRef && "_f" in fieldRef);
1110
+ }
1111
+ function isEmptyDirtyContainer(value) {
1112
+ return Array.isArray(value) ? !value.some((item) => !isUndefined(item)) : !Object.keys(value).length;
1113
+ }
1114
+ function clearDirtyField(container, key) {
1115
+ if (Array.isArray(container)) {
1116
+ container[key] = void 0;
1117
+ } else {
1118
+ delete container[key];
1119
+ }
1120
+ }
1121
+ function markFieldsDirty(data, fields = {}, fieldRefs) {
1122
+ for (const key in data) {
1123
+ const value = data[key];
1124
+ const fieldRef = fieldRefs && fieldRefs[key];
1125
+ if (isTraversable(value) && (!Array.isArray(value) || !isRegisteredLeaf(fieldRef))) {
1126
+ fields[key] = Array.isArray(value) ? [] : {};
1127
+ markFieldsDirty(value, fields[key], fieldRef);
1128
+ if (isEmptyDirtyContainer(fields[key])) {
1129
+ clearDirtyField(fields, key);
957
1130
  }
1131
+ } else if (!isUndefined(value)) {
1132
+ fields[key] = true;
958
1133
  }
959
1134
  }
960
1135
  return fields;
961
1136
  }
962
- function getDirtyFieldsFromDefaultValues(data, formValues, dirtyFieldsFromValues) {
963
- const isParentNodeArray = Array.isArray(data);
964
- if (isObject(data) || isParentNodeArray) {
965
- for (const key in data) {
966
- if (Array.isArray(data[key]) || isObject(data[key]) && !objectHasFunction(data[key])) {
967
- if (isUndefined(formValues) || isPrimitive(dirtyFieldsFromValues[key])) {
968
- dirtyFieldsFromValues[key] = Array.isArray(data[key]) ? markFieldsDirty(data[key], []) : { ...markFieldsDirty(data[key]) };
969
- } else {
970
- getDirtyFieldsFromDefaultValues(data[key], isNullOrUndefined(formValues) ? {} : formValues[key], dirtyFieldsFromValues[key]);
971
- }
1137
+ function getDirtyFields(data, formValues, dirtyFieldsFromValues, fieldRefs) {
1138
+ if (!dirtyFieldsFromValues) {
1139
+ dirtyFieldsFromValues = markFieldsDirty(formValues, {}, fieldRefs);
1140
+ }
1141
+ for (const key in data) {
1142
+ const value = data[key];
1143
+ const fieldRef = fieldRefs && fieldRefs[key];
1144
+ if (isTraversable(value) && (!Array.isArray(value) || !isRegisteredLeaf(fieldRef))) {
1145
+ if (isUndefined(formValues) || isPrimitive(dirtyFieldsFromValues[key])) {
1146
+ dirtyFieldsFromValues[key] = markFieldsDirty(value, Array.isArray(value) ? [] : {}, fieldRef);
972
1147
  } else {
973
- dirtyFieldsFromValues[key] = !deepEqual(data[key], formValues[key]);
1148
+ getDirtyFields(value, isNullOrUndefined(formValues) ? {} : formValues[key], dirtyFieldsFromValues[key], fieldRef);
974
1149
  }
1150
+ if (isEmptyDirtyContainer(dirtyFieldsFromValues[key])) {
1151
+ clearDirtyField(dirtyFieldsFromValues, key);
1152
+ }
1153
+ } else if (deepEqual(value, formValues[key])) {
1154
+ clearDirtyField(dirtyFieldsFromValues, key);
1155
+ } else {
1156
+ dirtyFieldsFromValues[key] = true;
975
1157
  }
976
1158
  }
977
1159
  return dirtyFieldsFromValues;
978
1160
  }
979
- var getDirtyFields = (defaultValues, formValues) => getDirtyFieldsFromDefaultValues(defaultValues, formValues, markFieldsDirty(formValues));
980
1161
  var getFieldValueAs = (value, { valueAsNumber, valueAsDate, setValueAs }) => isUndefined(value) ? value : valueAsNumber ? value === "" ? NaN : value ? +value : value : valueAsDate && isString(value) ? new Date(value) : setValueAs ? setValueAs(value) : value;
981
1162
  function getFieldValue(_f) {
982
1163
  const ref = _f.ref;
983
- if (_f.refs ? _f.refs.every((ref2) => ref2.disabled) : ref.disabled) {
984
- return;
985
- }
986
1164
  if (isFileInput(ref)) {
987
1165
  return ref.files;
988
1166
  }
@@ -1011,6 +1189,22 @@ var getResolverOptions = (fieldsNames, _fields, criteriaMode, shouldUseNativeVal
1011
1189
  };
1012
1190
  };
1013
1191
  var getRuleValue = (rule) => isUndefined(rule) ? rule : isRegex(rule) ? rule.source : isObject(rule) ? isRegex(rule.value) ? rule.value.source : rule.value : rule;
1192
+ const ASYNC_FUNCTION = "AsyncFunction";
1193
+ var hasPromiseValidation = (fieldReference) => {
1194
+ if (!fieldReference || !fieldReference.validate)
1195
+ return false;
1196
+ if (isFunction(fieldReference.validate)) {
1197
+ return fieldReference.validate.constructor.name === ASYNC_FUNCTION;
1198
+ }
1199
+ if (isObject(fieldReference.validate)) {
1200
+ for (const key in fieldReference.validate) {
1201
+ if (fieldReference.validate[key].constructor.name === ASYNC_FUNCTION) {
1202
+ return true;
1203
+ }
1204
+ }
1205
+ }
1206
+ return false;
1207
+ };
1014
1208
  var hasValidation = (options) => options.mount && (options.required || options.min || options.max || options.maxLength || options.minLength || options.pattern || options.validate);
1015
1209
  function schemaErrorLookup(errors, _fields, name) {
1016
1210
  const error = get(errors, name);
@@ -1034,12 +1228,25 @@ function schemaErrorLookup(errors, _fields, name) {
1034
1228
  error: foundError
1035
1229
  };
1036
1230
  }
1231
+ if (foundError && foundError.root && foundError.root.type) {
1232
+ return {
1233
+ name: `${fieldName}.root`,
1234
+ error: foundError.root
1235
+ };
1236
+ }
1037
1237
  names.pop();
1038
1238
  }
1039
1239
  return {
1040
1240
  name
1041
1241
  };
1042
1242
  }
1243
+ var shouldRenderFormState = (formStateData, _proxyFormState, updateFormState, isRoot) => {
1244
+ updateFormState(formStateData);
1245
+ const { name, ...formState } = formStateData;
1246
+ const keys = Object.keys(formState);
1247
+ return !keys.length || isRoot && keys.length >= Object.keys(_proxyFormState).length || keys.find((key) => _proxyFormState[key] === (!isRoot || VALIDATION_MODE.all));
1248
+ };
1249
+ var shouldSubscribeByName = (name, signalName, exact) => !name || !signalName || name === signalName || convertToArrayPayload(name).some((currentName) => currentName && (exact ? currentName === signalName || currentName.startsWith(signalName + ".") : currentName.startsWith(signalName) || signalName.startsWith(currentName)));
1043
1250
  var skipValidation = (isBlurEvent, isTouched, isSubmitted, reValidateMode, mode) => {
1044
1251
  if (mode.isOnAll) {
1045
1252
  return false;
@@ -1058,24 +1265,38 @@ const defaultOptions = {
1058
1265
  reValidateMode: VALIDATION_MODE.onChange,
1059
1266
  shouldFocusError: true
1060
1267
  };
1061
- function createFormControl(props = {}, flushRootRender) {
1268
+ const FORM_ERROR_TYPE = "form";
1269
+ const updateDirtyFields = (dirtyFields, nextDirtyFields) => {
1270
+ for (const key in dirtyFields) {
1271
+ if (!(key in nextDirtyFields)) {
1272
+ delete dirtyFields[key];
1273
+ }
1274
+ }
1275
+ Object.assign(dirtyFields, nextDirtyFields);
1276
+ };
1277
+ const DEFAULT_FORM_STATE = {
1278
+ submitCount: 0,
1279
+ isDirty: false,
1280
+ isReady: false,
1281
+ isValidating: false,
1282
+ isSubmitted: false,
1283
+ isSubmitting: false,
1284
+ isSubmitSuccessful: false,
1285
+ isValid: false,
1286
+ touchedFields: {},
1287
+ dirtyFields: {},
1288
+ validatingFields: {}
1289
+ };
1290
+ function createFormControl(props = {}) {
1062
1291
  let _options = {
1063
1292
  ...defaultOptions,
1064
1293
  ...props
1065
1294
  };
1066
1295
  let _formState = {
1067
- submitCount: 0,
1068
- isDirty: false,
1296
+ ...cloneObject(DEFAULT_FORM_STATE),
1069
1297
  isLoading: isFunction(_options.defaultValues),
1070
- isValidating: false,
1071
- isSubmitted: false,
1072
- isSubmitting: false,
1073
- isSubmitSuccessful: false,
1074
- isValid: false,
1075
- touchedFields: {},
1076
- dirtyFields: {},
1077
1298
  errors: _options.errors || {},
1078
- disabled: false
1299
+ disabled: _options.disabled || false
1079
1300
  };
1080
1301
  let _fields = {};
1081
1302
  let _defaultValues = isObject(_options.defaultValues) || isObject(_options.values) ? cloneObject(_options.defaultValues || _options.values) || {} : {};
@@ -1083,52 +1304,89 @@ function createFormControl(props = {}, flushRootRender) {
1083
1304
  let _state = {
1084
1305
  action: false,
1085
1306
  mount: false,
1086
- watch: false
1307
+ watch: false,
1308
+ keepIsValid: false
1087
1309
  };
1088
1310
  let _names = {
1089
1311
  mount: /* @__PURE__ */ new Set(),
1312
+ disabled: /* @__PURE__ */ new Set(),
1090
1313
  unMount: /* @__PURE__ */ new Set(),
1091
1314
  array: /* @__PURE__ */ new Set(),
1092
- watch: /* @__PURE__ */ new Set()
1315
+ watch: /* @__PURE__ */ new Set(),
1316
+ registerName: /* @__PURE__ */ new Set()
1093
1317
  };
1094
- let delayErrorCallback;
1095
- let timer = 0;
1096
- const _proxyFormState = {
1318
+ const delayErrorCallbacks = {};
1319
+ const timers = {};
1320
+ let _valuesSubscriberCount = 0;
1321
+ let _validationModeBeforeSubmit = getValidationModes(_options.mode);
1322
+ let _validationModeAfterSubmit = getValidationModes(_options.reValidateMode);
1323
+ const defaultProxyFormState = {
1097
1324
  isDirty: false,
1098
1325
  dirtyFields: false,
1326
+ validatingFields: false,
1099
1327
  touchedFields: false,
1100
1328
  isValidating: false,
1101
1329
  isValid: false,
1102
1330
  errors: false
1103
1331
  };
1332
+ const _proxyFormState = {
1333
+ ...defaultProxyFormState
1334
+ };
1335
+ let _proxySubscribeFormState = {
1336
+ ..._proxyFormState
1337
+ };
1104
1338
  const _subjects = {
1105
- values: createSubject(),
1106
1339
  array: createSubject(),
1107
1340
  state: createSubject()
1108
1341
  };
1109
- const shouldCaptureDirtyFields = props.resetOptions && props.resetOptions.keepDirtyValues;
1110
- const validationModeBeforeSubmit = getValidationModes(_options.mode);
1111
- const validationModeAfterSubmit = getValidationModes(_options.reValidateMode);
1342
+ let _setValidCallId = 0;
1112
1343
  const shouldDisplayAllAssociatedErrors = _options.criteriaMode === VALIDATION_MODE.all;
1113
- const debounce = (callback) => (wait) => {
1114
- clearTimeout(timer);
1115
- timer = setTimeout(callback, wait);
1116
- };
1117
- const _updateValid = async (shouldUpdateValid) => {
1118
- if (_proxyFormState.isValid || shouldUpdateValid) {
1119
- const isValid = _options.resolver ? isEmptyObject((await _executeSchema()).errors) : await executeBuiltInValidation(_fields, true);
1120
- if (isValid !== _formState.isValid) {
1344
+ const debounce = (name, callback) => (wait) => {
1345
+ clearTimeout(timers[name]);
1346
+ timers[name] = setTimeout(callback, wait);
1347
+ };
1348
+ const _setValid = async (shouldUpdateValid) => {
1349
+ if (_state.keepIsValid) {
1350
+ return;
1351
+ }
1352
+ if (!_options.disabled && (_proxyFormState.isValid || _proxySubscribeFormState.isValid || shouldUpdateValid)) {
1353
+ const callId = ++_setValidCallId;
1354
+ let isValid;
1355
+ if (_options.resolver) {
1356
+ isValid = isEmptyObject((await _runSchema()).errors);
1357
+ callId === _setValidCallId && _updateIsValidating();
1358
+ } else {
1359
+ isValid = await executeBuiltInValidation({
1360
+ fields: _fields,
1361
+ onlyCheckValid: true,
1362
+ eventType: EVENTS.VALID
1363
+ });
1364
+ }
1365
+ if (callId === _setValidCallId && isValid !== _formState.isValid) {
1121
1366
  _subjects.state.next({
1122
1367
  isValid
1123
1368
  });
1124
1369
  }
1125
1370
  }
1126
1371
  };
1127
- const _updateIsValidating = (value) => _proxyFormState.isValidating && _subjects.state.next({
1128
- isValidating: value
1129
- });
1130
- const _updateFieldArray = (name, values = [], method, args, shouldSetValues = true, shouldUpdateFieldsAndState = true) => {
1131
- if (args && method) {
1372
+ const _updateIsValidating = (names, isValidating) => {
1373
+ if (!_options.disabled && (_proxyFormState.isValidating || _proxyFormState.validatingFields || _proxySubscribeFormState.isValidating || _proxySubscribeFormState.validatingFields)) {
1374
+ (names || Array.from(_names.mount)).forEach((name) => {
1375
+ if (name) {
1376
+ isValidating ? set(_formState.validatingFields, name, isValidating) : unset(_formState.validatingFields, name);
1377
+ }
1378
+ });
1379
+ _subjects.state.next({
1380
+ validatingFields: _formState.validatingFields,
1381
+ isValidating: !isEmptyObject(_formState.validatingFields)
1382
+ });
1383
+ }
1384
+ };
1385
+ const _updateDirtyFields = () => {
1386
+ _formState.dirtyFields = getDirtyFields(_defaultValues, _formValues, void 0, _fields);
1387
+ };
1388
+ const _setFieldArray = (name, values = [], method, args, shouldSetValues = true, shouldUpdateFieldsAndState = true) => {
1389
+ if (args && method && !_options.disabled) {
1132
1390
  _state.action = true;
1133
1391
  if (shouldUpdateFieldsAndState && Array.isArray(get(_fields, name))) {
1134
1392
  const fieldValues = method(get(_fields, name), args.argA, args.argB);
@@ -1139,12 +1397,12 @@ function createFormControl(props = {}, flushRootRender) {
1139
1397
  shouldSetValues && set(_formState.errors, name, errors);
1140
1398
  unsetEmptyArray(_formState.errors, name);
1141
1399
  }
1142
- if (_proxyFormState.touchedFields && shouldUpdateFieldsAndState && Array.isArray(get(_formState.touchedFields, name))) {
1400
+ if ((_proxyFormState.touchedFields || _proxySubscribeFormState.touchedFields) && shouldUpdateFieldsAndState && Array.isArray(get(_formState.touchedFields, name))) {
1143
1401
  const touchedFields = method(get(_formState.touchedFields, name), args.argA, args.argB);
1144
1402
  shouldSetValues && set(_formState.touchedFields, name, touchedFields);
1145
1403
  }
1146
- if (_proxyFormState.dirtyFields) {
1147
- _formState.dirtyFields = getDirtyFields(_defaultValues, _formValues);
1404
+ if (_proxyFormState.dirtyFields || _proxySubscribeFormState.dirtyFields) {
1405
+ _updateDirtyFields();
1148
1406
  }
1149
1407
  _subjects.state.next({
1150
1408
  name,
@@ -1159,6 +1417,7 @@ function createFormControl(props = {}, flushRootRender) {
1159
1417
  };
1160
1418
  const updateErrors = (name, error) => {
1161
1419
  set(_formState.errors, name, error);
1420
+ _formState.errors = { ..._formState.errors };
1162
1421
  _subjects.state.next({
1163
1422
  errors: _formState.errors
1164
1423
  });
@@ -1170,12 +1429,42 @@ function createFormControl(props = {}, flushRootRender) {
1170
1429
  isValid: false
1171
1430
  });
1172
1431
  };
1432
+ const hasExplicitNullIntermediate = (name) => {
1433
+ const segments = isKey(name) ? [name] : stringToPath(name);
1434
+ let formValues = _formValues;
1435
+ let defaultValues = _defaultValues;
1436
+ for (let i = 0; i < segments.length - 1; i++) {
1437
+ const key = segments[i];
1438
+ formValues = isNullOrUndefined(formValues) ? formValues : formValues[key];
1439
+ defaultValues = isNullOrUndefined(defaultValues) ? defaultValues : defaultValues[key];
1440
+ if (formValues === null && defaultValues !== null) {
1441
+ return true;
1442
+ }
1443
+ }
1444
+ return false;
1445
+ };
1173
1446
  const updateValidAndValue = (name, shouldSkipSetValueAs, value, ref) => {
1174
1447
  const field = get(_fields, name);
1175
1448
  if (field) {
1449
+ if (hasExplicitNullIntermediate(name)) {
1450
+ return;
1451
+ }
1452
+ const wasUnsetInFormValues = isUndefined(get(_formValues, name));
1176
1453
  const defaultValue = get(_formValues, name, isUndefined(value) ? get(_defaultValues, name) : value);
1177
1454
  isUndefined(defaultValue) || ref && ref.defaultChecked || shouldSkipSetValueAs ? set(_formValues, name, shouldSkipSetValueAs ? defaultValue : getFieldValue(field._f)) : setFieldValue(name, defaultValue);
1178
- _state.mount && _updateValid();
1455
+ if (_state.mount && !_state.action) {
1456
+ _setValid();
1457
+ if (wasUnsetInFormValues && _formState.isDirty && (_proxyFormState.isDirty || _proxySubscribeFormState.isDirty)) {
1458
+ const isDirty = _getDirty();
1459
+ if (!isDirty) {
1460
+ _formState.isDirty = false;
1461
+ _subjects.state.next({ ..._formState });
1462
+ }
1463
+ }
1464
+ if (props.shouldUnregister && wasUnsetInFormValues && !isUndefined(get(_formValues, name)) && isWatched(name, _names)) {
1465
+ _state.watch = true;
1466
+ }
1467
+ }
1179
1468
  }
1180
1469
  };
1181
1470
  const updateTouchAndDirty = (name, fieldValue, isBlurEvent, shouldDirty, shouldRender) => {
@@ -1184,40 +1473,46 @@ function createFormControl(props = {}, flushRootRender) {
1184
1473
  const output = {
1185
1474
  name
1186
1475
  };
1187
- const disabledField = get(_fields, name) && get(_fields, name)._f.disabled;
1188
- if (!isBlurEvent || shouldDirty) {
1189
- if (_proxyFormState.isDirty) {
1190
- isPreviousDirty = _formState.isDirty;
1191
- _formState.isDirty = output.isDirty = _getDirty();
1192
- shouldUpdateField = isPreviousDirty !== output.isDirty;
1193
- }
1194
- const isCurrentFieldPristine = disabledField || deepEqual(get(_defaultValues, name), fieldValue);
1195
- isPreviousDirty = !disabledField && get(_formState.dirtyFields, name);
1196
- isCurrentFieldPristine || disabledField ? unset(_formState.dirtyFields, name) : set(_formState.dirtyFields, name, true);
1197
- output.dirtyFields = _formState.dirtyFields;
1198
- shouldUpdateField = shouldUpdateField || _proxyFormState.dirtyFields && isPreviousDirty !== !isCurrentFieldPristine;
1199
- }
1200
- if (isBlurEvent) {
1201
- const isPreviousFieldTouched = get(_formState.touchedFields, name);
1202
- if (!isPreviousFieldTouched) {
1203
- set(_formState.touchedFields, name, isBlurEvent);
1204
- output.touchedFields = _formState.touchedFields;
1205
- shouldUpdateField = shouldUpdateField || _proxyFormState.touchedFields && isPreviousFieldTouched !== isBlurEvent;
1206
- }
1207
- }
1208
- shouldUpdateField && shouldRender && _subjects.state.next(output);
1476
+ if (!_options.disabled || shouldDirty === true) {
1477
+ if (!isBlurEvent || shouldDirty) {
1478
+ const isCurrentFieldPristine = deepEqual(get(_defaultValues, name), fieldValue);
1479
+ if (_proxyFormState.isDirty || _proxySubscribeFormState.isDirty) {
1480
+ isPreviousDirty = _formState.isDirty;
1481
+ _formState.isDirty = output.isDirty = !isCurrentFieldPristine || _getDirty();
1482
+ shouldUpdateField = isPreviousDirty !== output.isDirty;
1483
+ }
1484
+ isPreviousDirty = !!get(_formState.dirtyFields, name);
1485
+ if (isCurrentFieldPristine !== _formState.isDirty) {
1486
+ updateDirtyFields(_formState.dirtyFields, getDirtyFields(_defaultValues, _formValues, void 0, _fields));
1487
+ } else {
1488
+ isCurrentFieldPristine ? unset(_formState.dirtyFields, name) : set(_formState.dirtyFields, name, true);
1489
+ }
1490
+ output.dirtyFields = _formState.dirtyFields;
1491
+ shouldUpdateField = shouldUpdateField || (_proxyFormState.dirtyFields || _proxySubscribeFormState.dirtyFields) && isPreviousDirty !== !isCurrentFieldPristine;
1492
+ }
1493
+ if (isBlurEvent) {
1494
+ const isPreviousFieldTouched = get(_formState.touchedFields, name);
1495
+ if (!isPreviousFieldTouched) {
1496
+ set(_formState.touchedFields, name, isBlurEvent);
1497
+ output.touchedFields = _formState.touchedFields;
1498
+ shouldUpdateField = shouldUpdateField || (_proxyFormState.touchedFields || _proxySubscribeFormState.touchedFields) && isPreviousFieldTouched !== isBlurEvent;
1499
+ }
1500
+ }
1501
+ shouldUpdateField && shouldRender && _subjects.state.next(output);
1502
+ }
1209
1503
  return shouldUpdateField ? output : {};
1210
1504
  };
1211
1505
  const shouldRenderByError = (name, isValid, error, fieldState) => {
1212
1506
  const previousFieldError = get(_formState.errors, name);
1213
- const shouldUpdateValid = _proxyFormState.isValid && isBoolean(isValid) && _formState.isValid !== isValid;
1214
- if (props.delayError && error) {
1215
- delayErrorCallback = debounce(() => updateErrors(name, error));
1216
- delayErrorCallback(props.delayError);
1507
+ const shouldUpdateValid = (_proxyFormState.isValid || _proxySubscribeFormState.isValid) && isBoolean(isValid) && _formState.isValid !== isValid;
1508
+ if (_options.delayError && error) {
1509
+ delayErrorCallbacks[name] = debounce(name, () => updateErrors(name, error));
1510
+ delayErrorCallbacks[name](_options.delayError);
1217
1511
  } else {
1218
- clearTimeout(timer);
1219
- delayErrorCallback = null;
1512
+ clearTimeout(timers[name]);
1513
+ delete delayErrorCallbacks[name];
1220
1514
  error ? set(_formState.errors, name, error) : unset(_formState.errors, name);
1515
+ _formState.errors = { ..._formState.errors };
1221
1516
  }
1222
1517
  if ((error ? !deepEqual(previousFieldError, error) : previousFieldError) || !isEmptyObject(fieldState) || shouldUpdateValid) {
1223
1518
  const updatedFormState = {
@@ -1232,40 +1527,105 @@ function createFormControl(props = {}, flushRootRender) {
1232
1527
  };
1233
1528
  _subjects.state.next(updatedFormState);
1234
1529
  }
1235
- _updateIsValidating(false);
1236
1530
  };
1237
- const _executeSchema = async (name) => _options.resolver(_formValues, _options.context, getResolverOptions(name || _names.mount, _fields, _options.criteriaMode, _options.shouldUseNativeValidation));
1531
+ const _runSchema = async (name) => {
1532
+ _updateIsValidating(name, true);
1533
+ return await _options.resolver(_formValues, _options.context, getResolverOptions(name || _names.mount, _fields, _options.criteriaMode, _options.shouldUseNativeValidation));
1534
+ };
1238
1535
  const executeSchemaAndUpdateState = async (names) => {
1239
- const { errors } = await _executeSchema(names);
1536
+ const { errors } = await _runSchema(names);
1537
+ _updateIsValidating(names);
1240
1538
  if (names) {
1241
1539
  for (const name of names) {
1242
1540
  const error = get(errors, name);
1243
- error ? set(_formState.errors, name, error) : unset(_formState.errors, name);
1541
+ error ? _names.array.has(name) && isObject(error) && !Object.keys(error).some((key) => !Number.isNaN(Number(key))) ? updateFieldArrayRootError(_formState.errors, { [name]: error }, name) : set(_formState.errors, name, error) : unset(_formState.errors, name);
1244
1542
  }
1543
+ _formState.errors = { ..._formState.errors };
1245
1544
  } else {
1246
1545
  _formState.errors = errors;
1247
1546
  }
1248
1547
  return errors;
1249
1548
  };
1250
- const executeBuiltInValidation = async (fields, shouldOnlyCheckValid, context = {
1251
- valid: true
1252
- }) => {
1253
- for (const name in fields) {
1254
- const field = fields[name];
1549
+ const validateForm = async ({ name, eventType }) => {
1550
+ if (props.validate) {
1551
+ const result = await props.validate({
1552
+ formValues: _formValues,
1553
+ formState: _formState,
1554
+ name,
1555
+ eventType
1556
+ });
1557
+ if (isObject(result)) {
1558
+ for (const key in result) {
1559
+ const error = result[key];
1560
+ if (error) {
1561
+ setError(`${FORM_ERROR_TYPE}.${key}`, {
1562
+ message: isString(error.message) ? error.message : "",
1563
+ type: error.type || INPUT_VALIDATION_RULES.validate
1564
+ });
1565
+ }
1566
+ }
1567
+ } else if (isString(result) || !result) {
1568
+ setError(FORM_ERROR_TYPE, {
1569
+ message: result || "",
1570
+ type: INPUT_VALIDATION_RULES.validate
1571
+ });
1572
+ } else {
1573
+ clearErrors(FORM_ERROR_TYPE);
1574
+ }
1575
+ return result;
1576
+ }
1577
+ return true;
1578
+ };
1579
+ const executeBuiltInValidation = async ({ fields, onlyCheckValid, name, eventType, context = {
1580
+ valid: true,
1581
+ runRootValidation: false
1582
+ } }) => {
1583
+ if (props.validate) {
1584
+ context.runRootValidation = true;
1585
+ const result = await validateForm({
1586
+ name,
1587
+ eventType
1588
+ });
1589
+ if (!result) {
1590
+ context.valid = false;
1591
+ if (onlyCheckValid) {
1592
+ return context.valid;
1593
+ }
1594
+ }
1595
+ }
1596
+ for (const name2 in fields) {
1597
+ const field = fields[name2];
1255
1598
  if (field) {
1256
1599
  const { _f, ...fieldValue } = field;
1257
1600
  if (_f) {
1258
1601
  const isFieldArrayRoot = _names.array.has(_f.name);
1259
- const fieldError = await validateField(field, _formValues, shouldDisplayAllAssociatedErrors, _options.shouldUseNativeValidation && !shouldOnlyCheckValid, isFieldArrayRoot);
1602
+ const isPromiseFunction = field._f && hasPromiseValidation(field._f);
1603
+ const shouldTrackIsValidatingState = _proxyFormState.validatingFields || _proxyFormState.isValidating || _proxySubscribeFormState.validatingFields || _proxySubscribeFormState.isValidating;
1604
+ if (isPromiseFunction && shouldTrackIsValidatingState) {
1605
+ _updateIsValidating([_f.name], true);
1606
+ }
1607
+ const fieldError = await validateField(field, _names.disabled, _formValues, shouldDisplayAllAssociatedErrors, _options.shouldUseNativeValidation && !onlyCheckValid, isFieldArrayRoot);
1608
+ if (isPromiseFunction && shouldTrackIsValidatingState) {
1609
+ _updateIsValidating([_f.name]);
1610
+ }
1260
1611
  if (fieldError[_f.name]) {
1261
1612
  context.valid = false;
1262
- if (shouldOnlyCheckValid) {
1613
+ if (onlyCheckValid) {
1263
1614
  break;
1264
1615
  }
1265
1616
  }
1266
- !shouldOnlyCheckValid && (get(fieldError, _f.name) ? isFieldArrayRoot ? updateFieldArrayRootError(_formState.errors, fieldError, _f.name) : set(_formState.errors, _f.name, fieldError[_f.name]) : unset(_formState.errors, _f.name));
1617
+ !onlyCheckValid && (get(fieldError, _f.name) ? isFieldArrayRoot ? updateFieldArrayRootError(_formState.errors, fieldError, _f.name) : set(_formState.errors, _f.name, fieldError[_f.name]) : unset(_formState.errors, _f.name));
1618
+ if (props.shouldUseNativeValidation && fieldError[_f.name]) {
1619
+ break;
1620
+ }
1267
1621
  }
1268
- fieldValue && await executeBuiltInValidation(fieldValue, shouldOnlyCheckValid, context);
1622
+ !isEmptyObject(fieldValue) && await executeBuiltInValidation({
1623
+ context,
1624
+ onlyCheckValid,
1625
+ fields: fieldValue,
1626
+ name: name2,
1627
+ eventType
1628
+ });
1269
1629
  }
1270
1630
  }
1271
1631
  return context.valid;
@@ -1277,12 +1637,12 @@ function createFormControl(props = {}, flushRootRender) {
1277
1637
  }
1278
1638
  _names.unMount = /* @__PURE__ */ new Set();
1279
1639
  };
1280
- const _getDirty = (name, data) => (name && data && set(_formValues, name, data), !deepEqual(getValues(), _defaultValues));
1640
+ const _getDirty = (name, data) => (name && data && set(_formValues, name, data), !deepEqual(_state.mount ? _formValues : _defaultValues, _defaultValues));
1281
1641
  const _getWatch = (names, defaultValue, isGlobal) => generateWatchOutput(names, _names, {
1282
1642
  ..._state.mount ? _formValues : isUndefined(defaultValue) ? _defaultValues : isString(names) ? { [names]: defaultValue } : defaultValue
1283
1643
  }, isGlobal, defaultValue);
1284
- const _getFieldArray = (name) => compact(get(_state.mount ? _formValues : _defaultValues, name, props.shouldUnregister ? get(_defaultValues, name, []) : []));
1285
- const setFieldValue = (name, value, options = {}) => {
1644
+ const _getFieldArray = (name) => compact(get(_state.mount ? _formValues : _defaultValues, name, _options.shouldUnregister ? get(_defaultValues, name, []) : []));
1645
+ const setFieldValue = (name, value, options = {}, skipClone = false, skipRender = false) => {
1286
1646
  const field = get(_fields, name);
1287
1647
  let fieldValue = value;
1288
1648
  if (field) {
@@ -1294,7 +1654,15 @@ function createFormControl(props = {}, flushRootRender) {
1294
1654
  [...fieldReference.ref.options].forEach((optionRef) => optionRef.selected = fieldValue.includes(optionRef.value));
1295
1655
  } else if (fieldReference.refs) {
1296
1656
  if (isCheckBoxInput(fieldReference.ref)) {
1297
- fieldReference.refs.length > 1 ? fieldReference.refs.forEach((checkboxRef) => (!checkboxRef.defaultChecked || !checkboxRef.disabled) && (checkboxRef.checked = Array.isArray(fieldValue) ? !!fieldValue.find((data) => data === checkboxRef.value) : fieldValue === checkboxRef.value)) : fieldReference.refs[0] && (fieldReference.refs[0].checked = !!fieldValue);
1657
+ fieldReference.refs.forEach((checkboxRef) => {
1658
+ if (!checkboxRef.defaultChecked || !checkboxRef.disabled) {
1659
+ if (Array.isArray(fieldValue)) {
1660
+ checkboxRef.checked = !!fieldValue.find((data) => data === checkboxRef.value);
1661
+ } else {
1662
+ checkboxRef.checked = fieldValue === checkboxRef.value || !!fieldValue;
1663
+ }
1664
+ }
1665
+ });
1298
1666
  } else {
1299
1667
  fieldReference.refs.forEach((radioRef) => radioRef.checked = radioRef.value === fieldValue);
1300
1668
  }
@@ -1302,112 +1670,184 @@ function createFormControl(props = {}, flushRootRender) {
1302
1670
  fieldReference.ref.value = "";
1303
1671
  } else {
1304
1672
  fieldReference.ref.value = fieldValue;
1305
- if (!fieldReference.ref.type) {
1306
- _subjects.values.next({
1673
+ if (!fieldReference.ref.type && !skipRender) {
1674
+ _subjects.state.next({
1307
1675
  name,
1308
- values: { ..._formValues }
1676
+ values: skipClone ? _formValues : cloneObject(_formValues)
1309
1677
  });
1310
1678
  }
1311
1679
  }
1312
1680
  }
1313
1681
  }
1314
- (options.shouldDirty || options.shouldTouch) && updateTouchAndDirty(name, fieldValue, options.shouldTouch, options.shouldDirty, true);
1315
- options.shouldValidate && trigger(name);
1682
+ (options.shouldDirty || options.shouldTouch) && updateTouchAndDirty(name, fieldValue, options.shouldTouch, options.shouldDirty, !skipRender);
1683
+ options.shouldValidate && trigger(name, {
1684
+ delayError: options.delayError
1685
+ });
1316
1686
  };
1317
- const setValues = (name, value, options) => {
1687
+ const setFieldValues = (name, value, options, skipClone = false, skipRender = false) => {
1318
1688
  for (const fieldKey in value) {
1689
+ if (!value.hasOwnProperty(fieldKey)) {
1690
+ return;
1691
+ }
1319
1692
  const fieldValue = value[fieldKey];
1320
- const fieldName = `${name}.${fieldKey}`;
1693
+ const fieldName = name + "." + fieldKey;
1321
1694
  const field = get(_fields, fieldName);
1322
- (_names.array.has(name) || !isPrimitive(fieldValue) || field && !field._f) && !isDateObject(fieldValue) ? setValues(fieldName, fieldValue, options) : setFieldValue(fieldName, fieldValue, options);
1695
+ (_names.array.has(name) || isObject(fieldValue) || field && !field._f) && !isDateObject(fieldValue) ? setFieldValues(fieldName, fieldValue, options, skipClone, skipRender) : setFieldValue(fieldName, fieldValue, options, skipClone, skipRender);
1323
1696
  }
1324
1697
  };
1325
- const setValue = (name, value, options = {}) => {
1698
+ const _setValue = (name, value, options, skipClone, skipStateEmit = false) => {
1326
1699
  const field = get(_fields, name);
1327
1700
  const isFieldArray = _names.array.has(name);
1328
- const cloneValue = cloneObject(value);
1329
- set(_formValues, name, cloneValue);
1701
+ const cloneValue = skipClone ? value : cloneObject(value);
1702
+ const previousValue = get(_formValues, name);
1703
+ const isValueUnchanged = deepEqual(previousValue, cloneValue);
1704
+ if (!isValueUnchanged) {
1705
+ set(_formValues, name, cloneValue);
1706
+ }
1330
1707
  if (isFieldArray) {
1331
1708
  _subjects.array.next({
1332
1709
  name,
1333
- values: { ..._formValues }
1710
+ values: skipClone ? _formValues : cloneObject(_formValues)
1334
1711
  });
1335
- if ((_proxyFormState.isDirty || _proxyFormState.dirtyFields) && options.shouldDirty) {
1336
- _subjects.state.next({
1337
- name,
1338
- dirtyFields: getDirtyFields(_defaultValues, _formValues),
1339
- isDirty: _getDirty(name, cloneValue)
1340
- });
1712
+ if ((_proxyFormState.isDirty || _proxyFormState.dirtyFields || _proxySubscribeFormState.isDirty || _proxySubscribeFormState.dirtyFields) && options.shouldDirty) {
1713
+ _updateDirtyFields();
1714
+ if (!skipStateEmit) {
1715
+ _subjects.state.next({
1716
+ name,
1717
+ dirtyFields: _formState.dirtyFields,
1718
+ isDirty: _getDirty(name, cloneValue)
1719
+ });
1720
+ }
1341
1721
  }
1342
1722
  } else {
1343
- field && !field._f && !isNullOrUndefined(cloneValue) ? setValues(name, cloneValue, options) : setFieldValue(name, cloneValue, options);
1723
+ const isEmpty = Array.isArray(cloneValue) && !cloneValue.length || isEmptyObject(cloneValue);
1724
+ if (!field || field._f || isNullOrUndefined(cloneValue) || isEmpty) {
1725
+ setFieldValue(name, cloneValue, options, skipClone, skipStateEmit);
1726
+ } else {
1727
+ setFieldValues(name, cloneValue, options, skipClone, skipStateEmit);
1728
+ }
1729
+ }
1730
+ if (!isValueUnchanged && !skipStateEmit) {
1731
+ const watched = isWatched(name, _names);
1732
+ const values = skipClone ? _formValues : cloneObject(_formValues);
1733
+ _subjects.state.next({
1734
+ ...watched && _formState,
1735
+ name: _state.mount || watched ? name : void 0,
1736
+ values
1737
+ });
1738
+ }
1739
+ };
1740
+ const setValue = (name, value, options = {}) => _setValue(name, value, options, false);
1741
+ const setValues = (formValues, options = {}) => {
1742
+ const updatedFormValues = isFunction(formValues) ? formValues(_formValues) : formValues;
1743
+ if (!deepEqual(_formValues, updatedFormValues)) {
1744
+ _formValues = {
1745
+ ..._formValues,
1746
+ ...updatedFormValues
1747
+ };
1748
+ const flattenedUpdates = flatten(updatedFormValues);
1749
+ for (const fieldName of _names.mount) {
1750
+ if (fieldName in flattenedUpdates) {
1751
+ _setValue(fieldName, flattenedUpdates[fieldName], options, true, true);
1752
+ }
1753
+ }
1754
+ _subjects.state.next({
1755
+ ..._formState,
1756
+ name: void 0,
1757
+ type: void 0,
1758
+ ..._valuesSubscriberCount ? { values: _formValues } : {}
1759
+ });
1760
+ if (options.shouldValidate) {
1761
+ _setValid();
1762
+ }
1344
1763
  }
1345
- isWatched(name, _names) && _subjects.state.next({ ..._formState });
1346
- _subjects.values.next({
1347
- name,
1348
- values: { ..._formValues }
1349
- });
1350
- !_state.mount && flushRootRender();
1351
1764
  };
1352
1765
  const onChange = async (event) => {
1766
+ _state.mount = true;
1353
1767
  const target = event.target;
1354
1768
  let name = target.name;
1355
1769
  let isFieldValueUpdated = true;
1356
1770
  const field = get(_fields, name);
1357
- const getCurrentFieldValue = () => target.type ? getFieldValue(field._f) : getEventValue(event);
1358
1771
  const _updateIsFieldValueUpdated = (fieldValue) => {
1359
- isFieldValueUpdated = Number.isNaN(fieldValue) || fieldValue === get(_formValues, name, fieldValue);
1772
+ isFieldValueUpdated = Number.isNaN(fieldValue) || isDateObject(fieldValue) && isNaN(fieldValue.getTime()) || deepEqual(fieldValue, get(_formValues, name, fieldValue));
1360
1773
  };
1361
1774
  if (field) {
1362
1775
  let error;
1363
1776
  let isValid;
1364
- const fieldValue = getCurrentFieldValue();
1777
+ const fieldValue = target.type ? getFieldValue(field._f) : getEventValue(event);
1365
1778
  const isBlurEvent = event.type === EVENTS.BLUR || event.type === EVENTS.FOCUS_OUT;
1366
- const shouldSkipValidation = !hasValidation(field._f) && !_options.resolver && !get(_formState.errors, name) && !field._f.deps || skipValidation(isBlurEvent, get(_formState.touchedFields, name), _formState.isSubmitted, validationModeAfterSubmit, validationModeBeforeSubmit);
1779
+ const hasNoValidationEffect = !hasValidation(field._f) && !props.validate && !_options.resolver && !get(_formState.errors, name) && !field._f.deps;
1780
+ const shouldSkipValidation = hasNoValidationEffect || skipValidation(isBlurEvent, get(_formState.touchedFields, name), _formState.isSubmitted, _validationModeAfterSubmit, _validationModeBeforeSubmit);
1367
1781
  const watched = isWatched(name, _names, isBlurEvent);
1368
1782
  set(_formValues, name, fieldValue);
1369
1783
  if (isBlurEvent) {
1370
- field._f.onBlur && field._f.onBlur(event);
1371
- delayErrorCallback && delayErrorCallback(0);
1784
+ if (!target || !target.readOnly) {
1785
+ field._f.onBlur && field._f.onBlur(event);
1786
+ const pendingDelayError = delayErrorCallbacks[name];
1787
+ pendingDelayError && pendingDelayError(0);
1788
+ }
1372
1789
  } else if (field._f.onChange) {
1373
1790
  field._f.onChange(event);
1374
1791
  }
1375
- const fieldState = updateTouchAndDirty(name, fieldValue, isBlurEvent, false);
1792
+ const fieldState = updateTouchAndDirty(name, fieldValue, isBlurEvent);
1376
1793
  const shouldRender = !isEmptyObject(fieldState) || watched;
1377
- !isBlurEvent && _subjects.values.next({
1794
+ !isBlurEvent && _subjects.state.next({
1378
1795
  name,
1379
1796
  type: event.type,
1380
- values: { ..._formValues }
1797
+ ..._valuesSubscriberCount ? { values: cloneObject(_formValues) } : {}
1381
1798
  });
1382
1799
  if (shouldSkipValidation) {
1383
- _proxyFormState.isValid && _updateValid();
1800
+ if ((!hasNoValidationEffect || !_formState.isValid) && (_proxyFormState.isValid || _proxySubscribeFormState.isValid)) {
1801
+ if (_options.mode === "onBlur") {
1802
+ if (isBlurEvent) {
1803
+ _setValid();
1804
+ }
1805
+ } else if (!isBlurEvent) {
1806
+ _setValid();
1807
+ }
1808
+ }
1384
1809
  return shouldRender && _subjects.state.next({ name, ...watched ? {} : fieldState });
1385
1810
  }
1811
+ if (!_options.resolver && props.validate) {
1812
+ await validateForm({
1813
+ name,
1814
+ eventType: event.type
1815
+ });
1816
+ }
1386
1817
  !isBlurEvent && watched && _subjects.state.next({ ..._formState });
1387
- _updateIsValidating(true);
1388
1818
  if (_options.resolver) {
1389
- const { errors } = await _executeSchema([name]);
1819
+ const { errors } = await _runSchema([name]);
1820
+ _updateIsValidating([name]);
1390
1821
  _updateIsFieldValueUpdated(fieldValue);
1391
- if (isFieldValueUpdated) {
1392
- const previousErrorLookupResult = schemaErrorLookup(_formState.errors, _fields, name);
1393
- const errorLookupResult = schemaErrorLookup(errors, _fields, previousErrorLookupResult.name || name);
1394
- error = errorLookupResult.error;
1395
- name = errorLookupResult.name;
1396
- isValid = isEmptyObject(errors);
1822
+ if (!isFieldValueUpdated) {
1823
+ !isEmptyObject(fieldState) && _subjects.state.next(fieldState);
1824
+ return;
1397
1825
  }
1826
+ const previousErrorLookupResult = schemaErrorLookup(_formState.errors, _fields, name);
1827
+ const errorLookupResult = schemaErrorLookup(errors, _fields, previousErrorLookupResult.name || name);
1828
+ error = errorLookupResult.error;
1829
+ name = errorLookupResult.name;
1830
+ isValid = isEmptyObject(errors);
1398
1831
  } else {
1399
- error = (await validateField(field, _formValues, shouldDisplayAllAssociatedErrors, _options.shouldUseNativeValidation))[name];
1832
+ _updateIsValidating([name], true);
1833
+ error = (await validateField(field, _names.disabled, _formValues, shouldDisplayAllAssociatedErrors, _options.shouldUseNativeValidation))[name];
1834
+ _updateIsValidating([name]);
1400
1835
  _updateIsFieldValueUpdated(fieldValue);
1401
1836
  if (isFieldValueUpdated) {
1402
1837
  if (error) {
1403
1838
  isValid = false;
1404
- } else if (_proxyFormState.isValid) {
1405
- isValid = await executeBuiltInValidation(_fields, true);
1839
+ } else if (_proxyFormState.isValid || _proxySubscribeFormState.isValid) {
1840
+ isValid = await executeBuiltInValidation({
1841
+ fields: _fields,
1842
+ onlyCheckValid: true,
1843
+ name,
1844
+ eventType: event.type
1845
+ });
1406
1846
  }
1407
1847
  }
1408
1848
  }
1409
1849
  if (isFieldValueUpdated) {
1410
- field._f.deps && trigger(field._f.deps);
1850
+ field._f.deps && (!Array.isArray(field._f.deps) || field._f.deps.length > 0) && trigger(field._f.deps);
1411
1851
  shouldRenderByError(name, isValid, error, fieldState);
1412
1852
  }
1413
1853
  }
@@ -1423,7 +1863,6 @@ function createFormControl(props = {}, flushRootRender) {
1423
1863
  let isValid;
1424
1864
  let validationResult;
1425
1865
  const fieldNames = convertToArrayPayload(name);
1426
- _updateIsValidating(true);
1427
1866
  if (_options.resolver) {
1428
1867
  const errors = await executeSchemaAndUpdateState(isUndefined(name) ? name : fieldNames);
1429
1868
  isValid = isEmptyObject(errors);
@@ -1431,43 +1870,77 @@ function createFormControl(props = {}, flushRootRender) {
1431
1870
  } else if (name) {
1432
1871
  validationResult = (await Promise.all(fieldNames.map(async (fieldName) => {
1433
1872
  const field = get(_fields, fieldName);
1434
- return await executeBuiltInValidation(field && field._f ? { [fieldName]: field } : field);
1873
+ return await executeBuiltInValidation({
1874
+ fields: field && field._f ? { [fieldName]: field } : field,
1875
+ eventType: EVENTS.TRIGGER
1876
+ });
1435
1877
  }))).every(Boolean);
1436
- !(!validationResult && !_formState.isValid) && _updateValid();
1878
+ !(!validationResult && !_formState.isValid) && _setValid();
1437
1879
  } else {
1438
- validationResult = isValid = await executeBuiltInValidation(_fields);
1880
+ validationResult = isValid = await executeBuiltInValidation({
1881
+ fields: _fields,
1882
+ name,
1883
+ eventType: EVENTS.TRIGGER
1884
+ });
1885
+ }
1886
+ if (options.delayError && _options.delayError && isString(name)) {
1887
+ const error = get(_formState.errors, name);
1888
+ if (error) {
1889
+ unset(_formState.errors, name);
1890
+ delayErrorCallbacks[name] = debounce(name, () => updateErrors(name, error));
1891
+ delayErrorCallbacks[name](_options.delayError);
1892
+ } else {
1893
+ clearTimeout(timers[name]);
1894
+ delete delayErrorCallbacks[name];
1895
+ }
1439
1896
  }
1440
1897
  _subjects.state.next({
1441
- ...!isString(name) || _proxyFormState.isValid && isValid !== _formState.isValid ? {} : { name },
1898
+ ...!isString(name) || (_proxyFormState.isValid || _proxySubscribeFormState.isValid) && isValid !== _formState.isValid ? {} : { name },
1442
1899
  ..._options.resolver || !name ? { isValid } : {},
1443
- errors: _formState.errors,
1444
- isValidating: false
1900
+ errors: _formState.errors
1445
1901
  });
1446
1902
  options.shouldFocus && !validationResult && iterateFieldsByAction(_fields, _focusInput, name ? fieldNames : _names.mount);
1447
1903
  return validationResult;
1448
1904
  };
1449
- const getValues = (fieldNames) => {
1450
- const values = {
1451
- ..._defaultValues,
1452
- ..._state.mount ? _formValues : {}
1905
+ const getValues = (fieldNames, config2) => {
1906
+ let values = {
1907
+ ..._state.mount ? _formValues : _defaultValues
1453
1908
  };
1909
+ if (config2) {
1910
+ values = extractFormValues(config2.dirtyFields ? _formState.dirtyFields : _formState.touchedFields, values);
1911
+ }
1454
1912
  return isUndefined(fieldNames) ? values : isString(fieldNames) ? get(values, fieldNames) : fieldNames.map((name) => get(values, name));
1455
1913
  };
1456
1914
  const getFieldState = (name, formState) => ({
1457
1915
  invalid: !!get((formState || _formState).errors, name),
1458
1916
  isDirty: !!get((formState || _formState).dirtyFields, name),
1459
- isTouched: !!get((formState || _formState).touchedFields, name),
1460
- error: get((formState || _formState).errors, name)
1917
+ error: get((formState || _formState).errors, name),
1918
+ isValidating: !!get(_formState.validatingFields, name),
1919
+ isTouched: !!get((formState || _formState).touchedFields, name)
1461
1920
  });
1462
1921
  const clearErrors = (name) => {
1463
- name && convertToArrayPayload(name).forEach((inputName) => unset(_formState.errors, inputName));
1464
- _subjects.state.next({
1465
- errors: name ? _formState.errors : {}
1466
- });
1922
+ const names = name ? convertToArrayPayload(name) : void 0;
1923
+ names === null || names === void 0 ? void 0 : names.forEach((inputName) => unset(_formState.errors, inputName));
1924
+ if (names) {
1925
+ names.forEach((inputName) => {
1926
+ _subjects.state.next({
1927
+ name: inputName,
1928
+ errors: _formState.errors
1929
+ });
1930
+ });
1931
+ } else {
1932
+ _formState.errors = {};
1933
+ _subjects.state.next({
1934
+ errors: _formState.errors
1935
+ });
1936
+ }
1467
1937
  };
1468
1938
  const setError = (name, error, options) => {
1469
1939
  const ref = (get(_fields, name, { _f: {} })._f || {}).ref;
1940
+ const currentError = get(_formState.errors, name) || {};
1941
+ const { ref: currentRef, message, type, ...restOfErrorTree } = currentError;
1470
1942
  set(_formState.errors, name, {
1943
+ ...restOfErrorTree,
1471
1944
  ...error,
1472
1945
  ref
1473
1946
  });
@@ -1478,9 +1951,72 @@ function createFormControl(props = {}, flushRootRender) {
1478
1951
  });
1479
1952
  options && options.shouldFocus && ref && ref.focus && ref.focus();
1480
1953
  };
1481
- const watch = (name, defaultValue) => isFunction(name) ? _subjects.values.subscribe({
1482
- next: (payload) => name(_getWatch(void 0, defaultValue), payload)
1483
- }) : _getWatch(name, defaultValue, true);
1954
+ const watch = (name, defaultValue) => {
1955
+ if (isFunction(name)) {
1956
+ _valuesSubscriberCount++;
1957
+ const { unsubscribe } = _subjects.state.subscribe({
1958
+ next: (payload) => "values" in payload && name(payload.values || _getWatch(void 0, defaultValue), payload)
1959
+ });
1960
+ let called = false;
1961
+ return {
1962
+ unsubscribe: () => {
1963
+ if (called) {
1964
+ return;
1965
+ }
1966
+ called = true;
1967
+ _valuesSubscriberCount--;
1968
+ unsubscribe();
1969
+ }
1970
+ };
1971
+ }
1972
+ return _getWatch(name, defaultValue, true);
1973
+ };
1974
+ const _subscribe = (props2) => {
1975
+ var _a;
1976
+ const needsValues = !!((_a = props2.formState) === null || _a === void 0 ? void 0 : _a.values);
1977
+ if (needsValues) {
1978
+ _valuesSubscriberCount++;
1979
+ }
1980
+ const { unsubscribe } = _subjects.state.subscribe({
1981
+ next: (formState) => {
1982
+ if (shouldSubscribeByName(props2.name, formState.name, props2.exact) && shouldRenderFormState(formState, props2.formState || _proxyFormState, _setFormState, props2.reRenderRoot)) {
1983
+ const snapshot = { ..._formValues };
1984
+ props2.callback({
1985
+ values: snapshot,
1986
+ ..._formState,
1987
+ ...formState,
1988
+ defaultValues: _defaultValues
1989
+ });
1990
+ }
1991
+ }
1992
+ });
1993
+ if (!needsValues) {
1994
+ return unsubscribe;
1995
+ }
1996
+ let called = false;
1997
+ return () => {
1998
+ if (called) {
1999
+ return;
2000
+ }
2001
+ called = true;
2002
+ _valuesSubscriberCount--;
2003
+ unsubscribe();
2004
+ };
2005
+ };
2006
+ const subscribe = (props2) => {
2007
+ _state.mount = true;
2008
+ _proxySubscribeFormState = {
2009
+ ..._proxySubscribeFormState,
2010
+ ...props2.formState
2011
+ };
2012
+ return _subscribe({
2013
+ ...props2,
2014
+ formState: {
2015
+ ...defaultProxyFormState,
2016
+ ...props2.formState
2017
+ }
2018
+ });
2019
+ };
1484
2020
  const unregister = (name, options = {}) => {
1485
2021
  for (const fieldName of name ? convertToArrayPayload(name) : _names.mount) {
1486
2022
  _names.mount.delete(fieldName);
@@ -1492,27 +2028,31 @@ function createFormControl(props = {}, flushRootRender) {
1492
2028
  !options.keepError && unset(_formState.errors, fieldName);
1493
2029
  !options.keepDirty && unset(_formState.dirtyFields, fieldName);
1494
2030
  !options.keepTouched && unset(_formState.touchedFields, fieldName);
2031
+ !options.keepIsValidating && unset(_formState.validatingFields, fieldName);
1495
2032
  !_options.shouldUnregister && !options.keepDefaultValue && unset(_defaultValues, fieldName);
1496
2033
  }
1497
- _subjects.values.next({
1498
- values: { ..._formValues }
2034
+ _subjects.state.next({
2035
+ values: cloneObject(_formValues)
1499
2036
  });
1500
2037
  _subjects.state.next({
1501
2038
  ..._formState,
1502
2039
  ...!options.keepDirty ? {} : { isDirty: _getDirty() }
1503
2040
  });
1504
- !options.keepIsValid && _updateValid();
2041
+ !options.keepIsValid && _setValid();
1505
2042
  };
1506
- const _updateDisabledField = ({ disabled, name, field, fields, value }) => {
1507
- if (isBoolean(disabled)) {
1508
- const inputValue = disabled ? void 0 : isUndefined(value) ? getFieldValue(field ? field._f : get(fields, name)._f) : value;
1509
- set(_formValues, name, inputValue);
1510
- updateTouchAndDirty(name, inputValue, false, false, true);
2043
+ const _setDisabledField = ({ disabled, name }) => {
2044
+ if (isBoolean(disabled) && _state.mount || !!disabled || _names.disabled.has(name)) {
2045
+ const wasDisabled = _names.disabled.has(name);
2046
+ const isDisabled = !!disabled;
2047
+ const disabledStateChanged = wasDisabled !== isDisabled;
2048
+ disabled ? _names.disabled.add(name) : _names.disabled.delete(name);
2049
+ disabledStateChanged && _state.mount && !_state.action && _setValid();
1511
2050
  }
1512
2051
  };
1513
2052
  const register = (name, options = {}) => {
1514
2053
  let field = get(_fields, name);
1515
- const disabledIsDefined = isBoolean(options.disabled);
2054
+ const disabledIsDefined = isBoolean(options.disabled) || isBoolean(_options.disabled);
2055
+ const shouldRevalidateRemount = !_names.registerName.has(name) && field && field._f && !field._f.mount;
1516
2056
  set(_fields, name, {
1517
2057
  ...field || {},
1518
2058
  _f: {
@@ -1523,17 +2063,16 @@ function createFormControl(props = {}, flushRootRender) {
1523
2063
  }
1524
2064
  });
1525
2065
  _names.mount.add(name);
1526
- if (field) {
1527
- _updateDisabledField({
1528
- field,
1529
- disabled: options.disabled,
2066
+ if (field && !shouldRevalidateRemount) {
2067
+ _setDisabledField({
2068
+ disabled: isBoolean(options.disabled) ? options.disabled : _options.disabled,
1530
2069
  name
1531
2070
  });
1532
2071
  } else {
1533
2072
  updateValidAndValue(name, true, options.value);
1534
2073
  }
1535
2074
  return {
1536
- ...disabledIsDefined ? { disabled: options.disabled } : {},
2075
+ ...disabledIsDefined ? { disabled: options.disabled || _options.disabled } : {},
1537
2076
  ..._options.progressive ? {
1538
2077
  required: !!options.required,
1539
2078
  min: getRuleValue(options.min),
@@ -1547,7 +2086,9 @@ function createFormControl(props = {}, flushRootRender) {
1547
2086
  onBlur: onChange,
1548
2087
  ref: (ref) => {
1549
2088
  if (ref) {
2089
+ _names.registerName.add(name);
1550
2090
  register(name, options);
2091
+ _names.registerName.delete(name);
1551
2092
  field = get(_fields, name);
1552
2093
  const fieldRef = isUndefined(ref.value) ? ref.querySelectorAll ? ref.querySelectorAll("input,select,textarea")[0] || ref : ref : ref;
1553
2094
  const radioOrCheckbox = isRadioOrCheckbox(fieldRef);
@@ -1555,18 +2096,22 @@ function createFormControl(props = {}, flushRootRender) {
1555
2096
  if (radioOrCheckbox ? refs.find((option) => option === fieldRef) : fieldRef === field._f.ref) {
1556
2097
  return;
1557
2098
  }
2099
+ const newField = {
2100
+ ...field._f
2101
+ };
2102
+ if (radioOrCheckbox) {
2103
+ newField.refs = [
2104
+ ...refs.filter(live),
2105
+ fieldRef,
2106
+ ...Array.isArray(get(_defaultValues, name)) ? [{}] : []
2107
+ ];
2108
+ newField.ref = { type: fieldRef.type, name };
2109
+ } else {
2110
+ newField.ref = fieldRef;
2111
+ delete newField.refs;
2112
+ }
1558
2113
  set(_fields, name, {
1559
- _f: {
1560
- ...field._f,
1561
- ...radioOrCheckbox ? {
1562
- refs: [
1563
- ...refs.filter(live),
1564
- fieldRef,
1565
- ...Array.isArray(get(_defaultValues, name)) ? [{}] : []
1566
- ],
1567
- ref: { type: fieldRef.type, name }
1568
- } : { ref: fieldRef }
1569
- }
2114
+ _f: newField
1570
2115
  });
1571
2116
  updateValidAndValue(name, false, void 0, fieldRef);
1572
2117
  } else {
@@ -1579,21 +2124,25 @@ function createFormControl(props = {}, flushRootRender) {
1579
2124
  }
1580
2125
  };
1581
2126
  };
1582
- const _focusError = () => _options.shouldFocusError && iterateFieldsByAction(_fields, _focusInput, _names.mount);
2127
+ const _focusError = () => _options.shouldFocusError && !_options.shouldUseNativeValidation && iterateFieldsByAction(_fields, _focusInput, _names.mount);
1583
2128
  const _disableForm = (disabled) => {
1584
2129
  if (isBoolean(disabled)) {
1585
2130
  _subjects.state.next({ disabled });
1586
2131
  iterateFieldsByAction(_fields, (ref, name) => {
1587
- let requiredDisabledState = disabled;
1588
2132
  const currentField = get(_fields, name);
1589
- if (currentField && isBoolean(currentField._f.disabled)) {
1590
- requiredDisabledState || (requiredDisabledState = currentField._f.disabled);
2133
+ if (currentField) {
2134
+ ref.disabled = currentField._f.disabled || disabled;
2135
+ if (Array.isArray(currentField._f.refs)) {
2136
+ currentField._f.refs.forEach((inputRef) => {
2137
+ inputRef.disabled = currentField._f.disabled || disabled;
2138
+ });
2139
+ }
1591
2140
  }
1592
- ref.disabled = requiredDisabledState;
1593
2141
  }, 0, false);
1594
2142
  }
1595
2143
  };
1596
2144
  const handleSubmit = (onValid, onInvalid) => async (e) => {
2145
+ let onValidError = void 0;
1597
2146
  if (e) {
1598
2147
  e.preventDefault && e.preventDefault();
1599
2148
  e.persist && e.persist();
@@ -1603,18 +2152,31 @@ function createFormControl(props = {}, flushRootRender) {
1603
2152
  isSubmitting: true
1604
2153
  });
1605
2154
  if (_options.resolver) {
1606
- const { errors, values } = await _executeSchema();
2155
+ const { errors, values } = await _runSchema();
2156
+ _updateIsValidating();
1607
2157
  _formState.errors = errors;
1608
- fieldValues = values;
2158
+ fieldValues = cloneObject(values);
1609
2159
  } else {
1610
- await executeBuiltInValidation(_fields);
2160
+ await executeBuiltInValidation({
2161
+ fields: _fields,
2162
+ eventType: EVENTS.SUBMIT
2163
+ });
1611
2164
  }
1612
- unset(_formState.errors, "root");
2165
+ if (_names.disabled.size) {
2166
+ for (const name of _names.disabled) {
2167
+ unset(fieldValues, name);
2168
+ }
2169
+ }
2170
+ unset(_formState.errors, ROOT_ERROR_TYPE);
1613
2171
  if (isEmptyObject(_formState.errors)) {
1614
2172
  _subjects.state.next({
1615
2173
  errors: {}
1616
2174
  });
1617
- await onValid(fieldValues, e);
2175
+ try {
2176
+ await onValid(fieldValues, e);
2177
+ } catch (error) {
2178
+ onValidError = error;
2179
+ }
1618
2180
  } else {
1619
2181
  if (onInvalid) {
1620
2182
  await onInvalid({ ..._formState.errors }, e);
@@ -1625,29 +2187,32 @@ function createFormControl(props = {}, flushRootRender) {
1625
2187
  _subjects.state.next({
1626
2188
  isSubmitted: true,
1627
2189
  isSubmitting: false,
1628
- isSubmitSuccessful: isEmptyObject(_formState.errors),
2190
+ isSubmitSuccessful: isEmptyObject(_formState.errors) && !onValidError,
1629
2191
  submitCount: _formState.submitCount + 1,
1630
2192
  errors: _formState.errors
1631
2193
  });
2194
+ if (onValidError) {
2195
+ throw onValidError;
2196
+ }
1632
2197
  };
1633
2198
  const resetField = (name, options = {}) => {
1634
2199
  if (get(_fields, name)) {
1635
2200
  if (isUndefined(options.defaultValue)) {
1636
- setValue(name, get(_defaultValues, name));
2201
+ setValue(name, cloneObject(get(_defaultValues, name)));
1637
2202
  } else {
1638
2203
  setValue(name, options.defaultValue);
1639
- set(_defaultValues, name, options.defaultValue);
2204
+ set(_defaultValues, name, cloneObject(options.defaultValue));
1640
2205
  }
1641
2206
  if (!options.keepTouched) {
1642
2207
  unset(_formState.touchedFields, name);
1643
2208
  }
1644
2209
  if (!options.keepDirty) {
1645
2210
  unset(_formState.dirtyFields, name);
1646
- _formState.isDirty = options.defaultValue ? _getDirty(name, get(_defaultValues, name)) : _getDirty();
2211
+ _formState.isDirty = options.defaultValue ? _getDirty(name, cloneObject(get(_defaultValues, name))) : _getDirty();
1647
2212
  }
1648
2213
  if (!options.keepError) {
1649
2214
  unset(_formState.errors, name);
1650
- _proxyFormState.isValid && _updateValid();
2215
+ _proxyFormState.isValid && _setValid();
1651
2216
  }
1652
2217
  _subjects.state.next({ ..._formState });
1653
2218
  }
@@ -1655,14 +2220,27 @@ function createFormControl(props = {}, flushRootRender) {
1655
2220
  const _reset = (formValues, keepStateOptions = {}) => {
1656
2221
  const updatedValues = formValues ? cloneObject(formValues) : _defaultValues;
1657
2222
  const cloneUpdatedValues = cloneObject(updatedValues);
1658
- const values = formValues && !isEmptyObject(formValues) ? cloneUpdatedValues : _defaultValues;
2223
+ const isEmptyResetValues = isEmptyObject(formValues);
2224
+ const values = cloneUpdatedValues;
2225
+ const fieldRefs = _fields;
1659
2226
  if (!keepStateOptions.keepDefaultValues) {
1660
2227
  _defaultValues = updatedValues;
1661
2228
  }
1662
2229
  if (!keepStateOptions.keepValues) {
1663
- if (keepStateOptions.keepDirtyValues || shouldCaptureDirtyFields) {
1664
- for (const fieldName of _names.mount) {
1665
- get(_formState.dirtyFields, fieldName) ? set(values, fieldName, get(_formValues, fieldName)) : setValue(fieldName, get(values, fieldName));
2230
+ if (keepStateOptions.keepDirtyValues) {
2231
+ const fieldsToCheck = /* @__PURE__ */ new Set([
2232
+ ..._names.mount,
2233
+ ...Object.keys(getDirtyFields(_defaultValues, _formValues, void 0, fieldRefs))
2234
+ ]);
2235
+ for (const fieldName of Array.from(fieldsToCheck)) {
2236
+ const isDirty = get(_formState.dirtyFields, fieldName);
2237
+ const existingValue = get(_formValues, fieldName);
2238
+ const newValue = get(values, fieldName);
2239
+ if (isDirty && !isUndefined(existingValue)) {
2240
+ set(values, fieldName, existingValue);
2241
+ } else if (!isDirty && !isUndefined(newValue)) {
2242
+ setValue(fieldName, newValue);
2243
+ }
1666
2244
  }
1667
2245
  } else {
1668
2246
  if (isWeb && isUndefined(formValues)) {
@@ -1680,54 +2258,81 @@ function createFormControl(props = {}, flushRootRender) {
1680
2258
  }
1681
2259
  }
1682
2260
  }
1683
- _fields = {};
2261
+ if (keepStateOptions.keepFieldsRef) {
2262
+ for (const fieldName of _names.mount) {
2263
+ setValue(fieldName, get(values, fieldName));
2264
+ }
2265
+ } else {
2266
+ _fields = {};
2267
+ }
2268
+ }
2269
+ if (_options.shouldUnregister) {
2270
+ _formValues = keepStateOptions.keepDefaultValues ? cloneObject(_defaultValues) : {};
2271
+ if (keepStateOptions.keepFieldsRef) {
2272
+ for (const fieldName of _names.mount) {
2273
+ set(_formValues, fieldName, get(values, fieldName));
2274
+ }
2275
+ }
2276
+ } else {
2277
+ _formValues = cloneObject(values);
1684
2278
  }
1685
- _formValues = props.shouldUnregister ? keepStateOptions.keepDefaultValues ? cloneObject(_defaultValues) : {} : cloneObject(values);
1686
2279
  _subjects.array.next({
1687
2280
  values: { ...values }
1688
2281
  });
1689
- _subjects.values.next({
2282
+ _subjects.state.next({
2283
+ name: void 0,
2284
+ type: void 0,
1690
2285
  values: { ...values }
1691
2286
  });
1692
2287
  }
1693
2288
  _names = {
1694
- mount: /* @__PURE__ */ new Set(),
2289
+ mount: keepStateOptions.keepDirtyValues ? _names.mount : /* @__PURE__ */ new Set(),
1695
2290
  unMount: /* @__PURE__ */ new Set(),
1696
2291
  array: /* @__PURE__ */ new Set(),
2292
+ registerName: /* @__PURE__ */ new Set(),
2293
+ disabled: /* @__PURE__ */ new Set(),
1697
2294
  watch: /* @__PURE__ */ new Set(),
1698
2295
  watchAll: false,
1699
2296
  focus: ""
1700
2297
  };
1701
- !_state.mount && flushRootRender();
1702
- _state.mount = !_proxyFormState.isValid || !!keepStateOptions.keepIsValid;
1703
- _state.watch = !!props.shouldUnregister;
2298
+ _state.mount = !_proxyFormState.isValid || !!keepStateOptions.keepIsValid || !!keepStateOptions.keepDirtyValues || !_options.shouldUnregister && !isEmptyObject(values);
2299
+ _state.watch = !!_options.shouldUnregister;
2300
+ _state.keepIsValid = !!keepStateOptions.keepIsValid;
2301
+ _state.action = false;
2302
+ if (!keepStateOptions.keepErrors) {
2303
+ _formState.errors = {};
2304
+ }
1704
2305
  _subjects.state.next({
1705
2306
  submitCount: keepStateOptions.keepSubmitCount ? _formState.submitCount : 0,
1706
- isDirty: keepStateOptions.keepDirty ? _formState.isDirty : !!(keepStateOptions.keepDefaultValues && !deepEqual(formValues, _defaultValues)),
2307
+ isDirty: isEmptyResetValues ? false : keepStateOptions.keepDirty ? _formState.isDirty : keepStateOptions.keepValues ? _getDirty() : !!(keepStateOptions.keepDefaultValues && !deepEqual(formValues, _defaultValues)),
1707
2308
  isSubmitted: keepStateOptions.keepIsSubmitted ? _formState.isSubmitted : false,
1708
- dirtyFields: keepStateOptions.keepDirtyValues ? _formState.dirtyFields : keepStateOptions.keepDefaultValues && formValues ? getDirtyFields(_defaultValues, formValues) : {},
2309
+ dirtyFields: isEmptyResetValues ? {} : keepStateOptions.keepDirtyValues ? keepStateOptions.keepDefaultValues && _formValues ? getDirtyFields(_defaultValues, _formValues, void 0, fieldRefs) : _formState.dirtyFields : keepStateOptions.keepDefaultValues && formValues ? getDirtyFields(_defaultValues, formValues, void 0, fieldRefs) : keepStateOptions.keepDirty ? _formState.dirtyFields : {},
1709
2310
  touchedFields: keepStateOptions.keepTouched ? _formState.touchedFields : {},
1710
2311
  errors: keepStateOptions.keepErrors ? _formState.errors : {},
1711
2312
  isSubmitSuccessful: keepStateOptions.keepIsSubmitSuccessful ? _formState.isSubmitSuccessful : false,
1712
- isSubmitting: false
2313
+ isSubmitting: false,
2314
+ defaultValues: _defaultValues
1713
2315
  });
1714
2316
  };
1715
- const reset = (formValues, keepStateOptions) => _reset(isFunction(formValues) ? formValues(_formValues) : formValues, keepStateOptions);
2317
+ const reset = (formValues, keepStateOptions) => _reset(isFunction(formValues) ? formValues(_formValues) : formValues, { ..._options.resetOptions, ...keepStateOptions });
1716
2318
  const setFocus = (name, options = {}) => {
1717
2319
  const field = get(_fields, name);
1718
2320
  const fieldReference = field && field._f;
1719
2321
  if (fieldReference) {
1720
2322
  const fieldRef = fieldReference.refs ? fieldReference.refs[0] : fieldReference.ref;
1721
2323
  if (fieldRef.focus) {
1722
- fieldRef.focus();
1723
- options.shouldSelect && fieldRef.select();
2324
+ setTimeout(() => {
2325
+ fieldRef.focus();
2326
+ options.shouldSelect && isFunction(fieldRef.select) && fieldRef.select();
2327
+ });
1724
2328
  }
1725
2329
  }
1726
2330
  };
1727
- const _updateFormState = (updatedFormState) => {
2331
+ const _setFormState = (updatedFormState) => {
2332
+ const { name, type, values, ...formState } = updatedFormState;
1728
2333
  _formState = {
1729
2334
  ..._formState,
1730
- ...updatedFormState
2335
+ ...formState
1731
2336
  };
1732
2337
  };
1733
2338
  const _resetDefaultValues = () => isFunction(_options.defaultValues) && _options.defaultValues().then((values) => {
@@ -1736,28 +2341,45 @@ function createFormControl(props = {}, flushRootRender) {
1736
2341
  isLoading: false
1737
2342
  });
1738
2343
  });
1739
- return {
2344
+ const resetDefaultValues = (values, options = {}) => {
2345
+ _defaultValues = cloneObject(values);
2346
+ if (!options.keepDirty) {
2347
+ const newDirtyFields = getDirtyFields(_defaultValues, _formValues, void 0, _fields);
2348
+ _formState.dirtyFields = newDirtyFields;
2349
+ _formState.isDirty = !isEmptyObject(newDirtyFields);
2350
+ }
2351
+ if (!options.keepIsValid) {
2352
+ _setValid();
2353
+ }
2354
+ _subjects.state.next({
2355
+ ..._formState,
2356
+ defaultValues: _defaultValues
2357
+ });
2358
+ };
2359
+ const methods = {
1740
2360
  control: {
1741
2361
  register,
1742
2362
  unregister,
1743
2363
  getFieldState,
1744
2364
  handleSubmit,
1745
2365
  setError,
1746
- _executeSchema,
2366
+ _subscribe,
2367
+ _runSchema,
2368
+ _updateIsValidating,
2369
+ _focusError,
1747
2370
  _getWatch,
1748
2371
  _getDirty,
1749
- _updateValid,
1750
- _removeUnmounted,
1751
- _updateFieldArray,
1752
- _updateDisabledField,
2372
+ _setValid,
2373
+ _setFieldArray,
2374
+ _setDisabledField,
2375
+ _setErrors,
1753
2376
  _getFieldArray,
1754
2377
  _reset,
1755
2378
  _resetDefaultValues,
1756
- _updateFormState,
2379
+ _removeUnmounted,
1757
2380
  _disableForm,
1758
2381
  _subjects,
1759
2382
  _proxyFormState,
1760
- _setErrors,
1761
2383
  get _fields() {
1762
2384
  return _fields;
1763
2385
  },
@@ -1782,9 +2404,6 @@ function createFormControl(props = {}, flushRootRender) {
1782
2404
  get _formState() {
1783
2405
  return _formState;
1784
2406
  },
1785
- set _formState(value) {
1786
- _formState = value;
1787
- },
1788
2407
  get _options() {
1789
2408
  return _options;
1790
2409
  },
@@ -1793,58 +2412,99 @@ function createFormControl(props = {}, flushRootRender) {
1793
2412
  ..._options,
1794
2413
  ...value
1795
2414
  };
2415
+ _validationModeBeforeSubmit = getValidationModes(_options.mode);
2416
+ _validationModeAfterSubmit = getValidationModes(_options.reValidateMode);
1796
2417
  }
1797
2418
  },
2419
+ subscribe,
1798
2420
  trigger,
1799
2421
  register,
1800
2422
  handleSubmit,
1801
2423
  watch,
1802
2424
  setValue,
2425
+ setValues,
1803
2426
  getValues,
1804
2427
  reset,
1805
2428
  resetField,
2429
+ resetDefaultValues,
1806
2430
  clearErrors,
1807
2431
  unregister,
1808
2432
  setError,
1809
2433
  setFocus,
1810
2434
  getFieldState
1811
2435
  };
2436
+ return {
2437
+ ...methods,
2438
+ formControl: methods
2439
+ };
1812
2440
  }
1813
2441
  function useForm(props = {}) {
1814
- const _formControl = React__default.default.useRef();
1815
- const _values = React__default.default.useRef();
1816
- const [formState, updateFormState] = React__default.default.useState({
1817
- isDirty: false,
1818
- isValidating: false,
2442
+ const _formControl = React__default.default.useRef(void 0);
2443
+ const _values = React__default.default.useRef(void 0);
2444
+ const _formControlProp = React__default.default.useRef(props.formControl);
2445
+ const [formState, updateFormState] = React__default.default.useState(() => ({
2446
+ ...cloneObject(DEFAULT_FORM_STATE),
1819
2447
  isLoading: isFunction(props.defaultValues),
1820
- isSubmitted: false,
1821
- isSubmitting: false,
1822
- isSubmitSuccessful: false,
1823
- isValid: false,
1824
- submitCount: 0,
1825
- dirtyFields: {},
1826
- touchedFields: {},
1827
2448
  errors: props.errors || {},
1828
- disabled: false,
2449
+ disabled: props.disabled || false,
1829
2450
  defaultValues: isFunction(props.defaultValues) ? void 0 : props.defaultValues
1830
- });
1831
- if (!_formControl.current) {
1832
- _formControl.current = {
1833
- ...createFormControl(props, () => updateFormState((formState2) => ({ ...formState2 }))),
1834
- formState
1835
- };
2451
+ }));
2452
+ if (!_formControl.current || props.formControl && _formControlProp.current !== props.formControl) {
2453
+ _formControlProp.current = props.formControl;
2454
+ if (props.formControl) {
2455
+ _formControl.current = {
2456
+ ...props.formControl,
2457
+ formState
2458
+ };
2459
+ if (props.defaultValues && !isFunction(props.defaultValues)) {
2460
+ props.formControl.reset(props.defaultValues, props.resetOptions);
2461
+ }
2462
+ } else {
2463
+ const { formControl, ...rest } = createFormControl(props);
2464
+ _formControl.current = {
2465
+ ...rest,
2466
+ formState
2467
+ };
2468
+ }
1836
2469
  }
1837
2470
  const control = _formControl.current.control;
1838
2471
  control._options = props;
1839
- useSubscribe({
1840
- subject: control._subjects.state,
1841
- next: (value) => {
1842
- if (shouldRenderFormState(value, control._proxyFormState, control._updateFormState, true)) {
1843
- updateFormState({ ...control._formState });
1844
- }
1845
- }
1846
- });
2472
+ useIsomorphicLayoutEffect(() => {
2473
+ const sub = control._subscribe({
2474
+ formState: control._proxyFormState,
2475
+ callback: () => updateFormState({
2476
+ ...control._formState,
2477
+ defaultValues: control._defaultValues
2478
+ }),
2479
+ reRenderRoot: true
2480
+ });
2481
+ updateFormState((data) => ({
2482
+ ...data,
2483
+ isReady: true
2484
+ }));
2485
+ control._formState.isReady = true;
2486
+ return sub;
2487
+ }, [control]);
1847
2488
  React__default.default.useEffect(() => control._disableForm(props.disabled), [control, props.disabled]);
2489
+ React__default.default.useEffect(() => {
2490
+ if (props.mode) {
2491
+ control._options.mode = props.mode;
2492
+ }
2493
+ if (props.reValidateMode) {
2494
+ control._options.reValidateMode = props.reValidateMode;
2495
+ }
2496
+ }, [control, props.mode, props.reValidateMode]);
2497
+ React__default.default.useEffect(() => {
2498
+ if (props.errors) {
2499
+ control._setErrors(props.errors);
2500
+ control._focusError();
2501
+ }
2502
+ }, [control, props.errors]);
2503
+ React__default.default.useEffect(() => {
2504
+ props.shouldUnregister && control._subjects.state.next({
2505
+ values: control._getWatch()
2506
+ });
2507
+ }, [control, props.shouldUnregister]);
1848
2508
  React__default.default.useEffect(() => {
1849
2509
  if (control._proxyFormState.isDirty) {
1850
2510
  const isDirty = control._getDirty();
@@ -1856,22 +2516,24 @@ function useForm(props = {}) {
1856
2516
  }
1857
2517
  }, [control, formState.isDirty]);
1858
2518
  React__default.default.useEffect(() => {
2519
+ var _a;
1859
2520
  if (props.values && !deepEqual(props.values, _values.current)) {
1860
- control._reset(props.values, control._options.resetOptions);
2521
+ control._reset(props.values, {
2522
+ keepFieldsRef: true,
2523
+ ...control._options.resetOptions
2524
+ });
2525
+ if (!((_a = control._options.resetOptions) === null || _a === void 0 ? void 0 : _a.keepIsValid)) {
2526
+ control._setValid();
2527
+ }
1861
2528
  _values.current = props.values;
1862
2529
  updateFormState((state) => ({ ...state }));
1863
2530
  } else {
1864
2531
  control._resetDefaultValues();
1865
2532
  }
1866
- }, [props.values, control]);
1867
- React__default.default.useEffect(() => {
1868
- if (props.errors) {
1869
- control._setErrors(props.errors);
1870
- }
1871
- }, [props.errors, control]);
2533
+ }, [control, props.values]);
1872
2534
  React__default.default.useEffect(() => {
1873
2535
  if (!control._state.mount) {
1874
- control._updateValid();
2536
+ control._setValid();
1875
2537
  control._state.mount = true;
1876
2538
  }
1877
2539
  if (control._state.watch) {
@@ -1880,7 +2542,7 @@ function useForm(props = {}) {
1880
2542
  }
1881
2543
  control._removeUnmounted();
1882
2544
  });
1883
- _formControl.current.formState = getProxyFormState(formState, control);
2545
+ _formControl.current.formState = React__default.default.useMemo(() => getProxyFormState(formState, control), [control, formState]);
1884
2546
  return _formControl.current;
1885
2547
  }
1886
2548
  const jsonToText = (v) => v == null || v === "" ? "" : JSON.stringify(v, null, 2);