@bombillazo/rhf-plus 7.62.0-plus.3 → 7.62.0-plus.5

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.
@@ -124,6 +124,8 @@ var set = (object, path, value) => {
124
124
  const EVENTS = {
125
125
  BLUR: 'blur',
126
126
  FOCUS_OUT: 'focusout',
127
+ FOCUS: 'focus',
128
+ FOCUS_IN: 'focusin',
127
129
  CHANGE: 'change',
128
130
  };
129
131
  const VALIDATION_MODE = {
@@ -271,6 +273,7 @@ function useFormState(props) {
271
273
  isLoading: false,
272
274
  dirtyFields: false,
273
275
  touchedFields: false,
276
+ focusedField: false,
274
277
  validatingFields: false,
275
278
  isValidating: false,
276
279
  isValid: false,
@@ -472,6 +475,10 @@ function useController(props) {
472
475
  enumerable: true,
473
476
  get: () => !!get(formState.touchedFields, name),
474
477
  },
478
+ isFocused: {
479
+ enumerable: true,
480
+ get: () => formState.focusedField === name,
481
+ },
475
482
  isValidating: {
476
483
  enumerable: true,
477
484
  get: () => !!get(formState.validatingFields, name),
@@ -495,6 +502,13 @@ function useController(props) {
495
502
  },
496
503
  type: EVENTS.BLUR,
497
504
  }), [name, control._formValues]);
505
+ const onFocus = React.useCallback(() => _registerProps.current.onFocus({
506
+ target: {
507
+ value: get(control._formValues, name),
508
+ name: name,
509
+ },
510
+ type: EVENTS.FOCUS,
511
+ }), [name, control._formValues]);
498
512
  const elementRef = React.useRef(null);
499
513
  const ref = React.useCallback((elm) => {
500
514
  elementRef.current = elm;
@@ -536,9 +550,19 @@ function useController(props) {
536
550
  ...(isBoolean(isFieldDisabled) ? { disabled: isFieldDisabled } : {}),
537
551
  onChange,
538
552
  onBlur,
553
+ onFocus,
539
554
  ref,
540
555
  };
541
- }, [name, disabled, control._options.disabled, onChange, onBlur, ref, value]);
556
+ }, [
557
+ name,
558
+ disabled,
559
+ control._options.disabled,
560
+ onChange,
561
+ onBlur,
562
+ onFocus,
563
+ ref,
564
+ value,
565
+ ]);
542
566
  React.useEffect(() => {
543
567
  const _shouldUnregisterField = control._options.shouldUnregister || shouldUnregister;
544
568
  control.register(name, {
@@ -1146,7 +1170,15 @@ var shouldSubscribeByName = (name, signalName, exact) => !name ||
1146
1170
  : currentName.startsWith(signalName) ||
1147
1171
  signalName.startsWith(currentName)));
1148
1172
 
1149
- var skipValidation = (isBlurEvent, isTouched, isSubmitted, reValidateMode, mode) => {
1173
+ var skipValidation = (isBlurEvent, isTouched, isSubmitted, reValidateMode, mode,
1174
+ /**
1175
+ * Need to keep this order of parameters for backward compatibility
1176
+ */
1177
+ isFocusEvent) => {
1178
+ // Focus events should always skip validation
1179
+ if (isFocusEvent) {
1180
+ return true;
1181
+ }
1150
1182
  if (mode.isOnAll) {
1151
1183
  return false;
1152
1184
  }
@@ -1413,6 +1445,7 @@ function createFormControl(props = {}) {
1413
1445
  isValid: false,
1414
1446
  touchedFields: {},
1415
1447
  dirtyFields: {},
1448
+ focusedField: undefined,
1416
1449
  validatingFields: {},
1417
1450
  errors: _options.errors || {},
1418
1451
  disabled: Array.isArray(_options.disabled)
@@ -1446,6 +1479,7 @@ function createFormControl(props = {}) {
1446
1479
  dirtyFields: false,
1447
1480
  validatingFields: false,
1448
1481
  touchedFields: false,
1482
+ focusedField: false,
1449
1483
  isValidating: false,
1450
1484
  isValid: false,
1451
1485
  errors: false,
@@ -1557,7 +1591,7 @@ function createFormControl(props = {}) {
1557
1591
  _state.mount && _setValid();
1558
1592
  }
1559
1593
  };
1560
- const updateTouchAndDirty = (name, fieldValue, isBlurEvent, shouldDirty, shouldRender) => {
1594
+ const updateTouchAndDirty = (name, fieldValue, isBlurEvent, isFocusEvent, shouldDirty, shouldRender) => {
1561
1595
  let shouldUpdateField = false;
1562
1596
  let isPreviousDirty = false;
1563
1597
  const output = {
@@ -1594,6 +1628,25 @@ function createFormControl(props = {}) {
1594
1628
  isPreviousFieldTouched !== isBlurEvent);
1595
1629
  }
1596
1630
  }
1631
+ // Handle focus state
1632
+ if (isFocusEvent || isBlurEvent) {
1633
+ const wasPreviouslyFocused = _formState.focusedField === name;
1634
+ const shouldBeFocused = isFocusEvent && !isBlurEvent;
1635
+ if (wasPreviouslyFocused !== shouldBeFocused) {
1636
+ if (shouldBeFocused) {
1637
+ _formState.focusedField = name;
1638
+ }
1639
+ else {
1640
+ _formState.focusedField = undefined;
1641
+ }
1642
+ output.focusedField = _formState.focusedField;
1643
+ shouldUpdateField =
1644
+ shouldUpdateField ||
1645
+ ((_proxyFormState.focusedField ||
1646
+ _proxySubscribeFormState.focusedField) &&
1647
+ wasPreviouslyFocused !== shouldBeFocused);
1648
+ }
1649
+ }
1597
1650
  shouldUpdateField && shouldRender && _subjects.state.next(output);
1598
1651
  }
1599
1652
  return shouldUpdateField ? output : {};
@@ -1759,7 +1812,8 @@ function createFormControl(props = {}) {
1759
1812
  }
1760
1813
  }
1761
1814
  (options.shouldDirty || options.shouldTouch) &&
1762
- updateTouchAndDirty(name, fieldValue, options.shouldTouch, options.shouldDirty, true);
1815
+ updateTouchAndDirty(name, fieldValue, options.shouldTouch, false, // isFocusEvent - not applicable for setValue
1816
+ options.shouldDirty, true);
1763
1817
  options.shouldValidate && trigger(name);
1764
1818
  };
1765
1819
  const setValues = (name, value, options) => {
@@ -1810,6 +1864,14 @@ function createFormControl(props = {}) {
1810
1864
  name: _state.mount ? name : undefined,
1811
1865
  values: cloneObject(_formValues),
1812
1866
  });
1867
+ // Trigger validation when shouldValidate is true
1868
+ // This ensures validation happens for all cases including:
1869
+ // - Field arrays
1870
+ // - Empty arrays
1871
+ // - Nested fields with array values
1872
+ if (options.shouldValidate) {
1873
+ trigger(name);
1874
+ }
1813
1875
  };
1814
1876
  const onChange = async (event) => {
1815
1877
  _state.mount = true;
@@ -1848,12 +1910,13 @@ function createFormControl(props = {}) {
1848
1910
  ? getFieldValue(field._f)
1849
1911
  : getEventValue(event);
1850
1912
  const isBlurEvent = event.type === EVENTS.BLUR || event.type === EVENTS.FOCUS_OUT;
1913
+ const isFocusEvent = event.type === EVENTS.FOCUS || event.type === EVENTS.FOCUS_IN;
1851
1914
  const shouldSkipValidation = (!hasValidation(field._f) &&
1852
1915
  !_options.resolver &&
1853
1916
  !get(_formState.errors, name) &&
1854
1917
  !field._f.deps) ||
1855
- skipValidation(isBlurEvent, get(_formState.touchedFields, name), _formState.isSubmitted, validationModeAfterSubmit, validationModeBeforeSubmit);
1856
- const watched = isWatched(name, _names, isBlurEvent);
1918
+ skipValidation(isBlurEvent, get(_formState.touchedFields, name), _formState.isSubmitted, validationModeAfterSubmit, validationModeBeforeSubmit, isFocusEvent);
1919
+ const watched = isWatched(name, _names, isBlurEvent || isFocusEvent);
1857
1920
  set(_formValues, name, fieldValue);
1858
1921
  if (isBlurEvent) {
1859
1922
  if (!target || !target.readOnly) {
@@ -1864,7 +1927,7 @@ function createFormControl(props = {}) {
1864
1927
  else if (field._f.onChange) {
1865
1928
  field._f.onChange(event);
1866
1929
  }
1867
- const fieldState = updateTouchAndDirty(name, fieldValue, isBlurEvent);
1930
+ const fieldState = updateTouchAndDirty(name, fieldValue, isBlurEvent, isFocusEvent);
1868
1931
  const shouldRender = !isEmptyObject(fieldState) || watched;
1869
1932
  !isBlurEvent &&
1870
1933
  _subjects.state.next({
@@ -1978,6 +2041,7 @@ function createFormControl(props = {}) {
1978
2041
  error: get((formState || _formState).errors, name),
1979
2042
  isValidating: !!get(_formState.validatingFields, name),
1980
2043
  isTouched: !!get((formState || _formState).touchedFields, name),
2044
+ isFocused: (formState || _formState).focusedField === name,
1981
2045
  });
1982
2046
  const clearErrors = (name) => {
1983
2047
  name &&
@@ -2117,6 +2181,7 @@ function createFormControl(props = {}) {
2117
2181
  name,
2118
2182
  onChange,
2119
2183
  onBlur: onChange,
2184
+ onFocus: onChange,
2120
2185
  ref: (ref) => {
2121
2186
  if (ref) {
2122
2187
  register(name, options);
@@ -2382,6 +2447,7 @@ function createFormControl(props = {}) {
2382
2447
  touchedFields: keepStateOptions.keepTouched
2383
2448
  ? _formState.touchedFields
2384
2449
  : {},
2450
+ focusedField: undefined, // Always reset focused field on form reset
2385
2451
  errors: keepStateOptions.keepErrors ? _formState.errors : {},
2386
2452
  isSubmitSuccessful: keepStateOptions.keepIsSubmitSuccessful
2387
2453
  ? _formState.isSubmitSuccessful
@@ -2898,6 +2964,7 @@ function useForm(props = {}) {
2898
2964
  submitCount: 0,
2899
2965
  dirtyFields: {},
2900
2966
  touchedFields: {},
2967
+ focusedField: undefined,
2901
2968
  validatingFields: {},
2902
2969
  errors: props.errors || {},
2903
2970
  // If it's an array, set formState.disabled to false because when using array mode,