@bombillazo/rhf-plus 7.71.2-plus.4 → 7.72.0-plus.0

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.
@@ -123,6 +123,9 @@ const EVENTS = {
123
123
  FOCUS: 'focus',
124
124
  FOCUS_IN: 'focusin',
125
125
  CHANGE: 'change',
126
+ SUBMIT: 'submit',
127
+ TRIGGER: 'trigger',
128
+ VALID: 'valid',
126
129
  };
127
130
  const VALIDATION_MODE = {
128
131
  onBlur: 'onBlur',
@@ -140,6 +143,8 @@ const INPUT_VALIDATION_RULES = {
140
143
  required: 'required',
141
144
  validate: 'validate',
142
145
  };
146
+ const FORM_ERROR_TYPE = 'form';
147
+ const ROOT_ERROR_TYPE = 'root';
143
148
 
144
149
  /**
145
150
  * Separate context for `control` to prevent unnecessary rerenders.
@@ -1337,7 +1342,7 @@ var unsetEmptyArray = (ref, name) => !compact(get(ref, name)).length && unset(re
1337
1342
 
1338
1343
  var updateFieldArrayRootError = (errors, error, name) => {
1339
1344
  const fieldArrayErrors = convertToArrayPayload(get(errors, name));
1340
- set(fieldArrayErrors, 'root', error[name]);
1345
+ set(fieldArrayErrors, ROOT_ERROR_TYPE, error[name]);
1341
1346
  set(errors, name, fieldArrayErrors);
1342
1347
  return errors;
1343
1348
  };
@@ -1641,7 +1646,11 @@ function createFormControl(props = {}) {
1641
1646
  _updateIsValidating();
1642
1647
  }
1643
1648
  else {
1644
- isValid = await executeBuiltInValidation(_fields, true);
1649
+ isValid = await executeBuiltInValidation({
1650
+ fields: _fields,
1651
+ onlyCheckValid: true,
1652
+ eventType: EVENTS.VALID,
1653
+ });
1645
1654
  }
1646
1655
  if (isValid !== _formState.isValid) {
1647
1656
  _subjects.state.next({
@@ -1690,7 +1699,9 @@ function createFormControl(props = {}) {
1690
1699
  shouldSetValues && set(_formState.touchedFields, name, touchedFields);
1691
1700
  }
1692
1701
  if (_proxyFormState.dirtyFields || _proxySubscribeFormState.dirtyFields) {
1693
- _formState.dirtyFields = getDirtyFields(_defaultValues, _formValues);
1702
+ const fullDirtyFields = getDirtyFields(_defaultValues, _formValues);
1703
+ const rootName = getNodeParentName(name);
1704
+ set(_formState.dirtyFields, rootName, get(fullDirtyFields, rootName));
1694
1705
  }
1695
1706
  _subjects.state.next({
1696
1707
  name,
@@ -1837,8 +1848,7 @@ function createFormControl(props = {}) {
1837
1848
  };
1838
1849
  const _runSchema = async (name) => {
1839
1850
  _updateIsValidating(name, true);
1840
- const result = await _options.resolver(_formValues, _options.context, getResolverOptions(name || _names.mount, _fields, _options.criteriaMode, _options.shouldUseNativeValidation));
1841
- return result;
1851
+ return await _options.resolver(_formValues, _options.context, getResolverOptions(name || _names.mount, _fields, _options.criteriaMode, _options.shouldUseNativeValidation));
1842
1852
  };
1843
1853
  const executeSchemaAndUpdateState = async (names) => {
1844
1854
  const { errors } = await _runSchema(names);
@@ -1856,9 +1866,55 @@ function createFormControl(props = {}) {
1856
1866
  }
1857
1867
  return errors;
1858
1868
  };
1859
- const executeBuiltInValidation = async (fields, shouldOnlyCheckValid, context = {
1869
+ const validateForm = async ({ name, eventType, }) => {
1870
+ if (props.validate) {
1871
+ const result = await props.validate({
1872
+ formValues: _formValues,
1873
+ formState: _formState,
1874
+ name,
1875
+ eventType,
1876
+ });
1877
+ if (isObject(result)) {
1878
+ for (const key in result) {
1879
+ const error = result[key];
1880
+ if (error) {
1881
+ setError(`${FORM_ERROR_TYPE}.${key}`, {
1882
+ message: isString(result.message) ? result.message : '',
1883
+ type: INPUT_VALIDATION_RULES.validate,
1884
+ });
1885
+ }
1886
+ }
1887
+ }
1888
+ else if (isString(result) || !result) {
1889
+ setError(FORM_ERROR_TYPE, {
1890
+ message: result || '',
1891
+ type: INPUT_VALIDATION_RULES.validate,
1892
+ });
1893
+ }
1894
+ else {
1895
+ clearErrors(FORM_ERROR_TYPE);
1896
+ }
1897
+ return result;
1898
+ }
1899
+ return true;
1900
+ };
1901
+ const executeBuiltInValidation = async ({ fields, onlyCheckValid, name, eventType, context = {
1860
1902
  valid: true,
1861
- }) => {
1903
+ runRootValidation: false,
1904
+ }, }) => {
1905
+ if (props.validate) {
1906
+ context.runRootValidation = true;
1907
+ const result = await validateForm({
1908
+ name,
1909
+ eventType,
1910
+ });
1911
+ if (!result) {
1912
+ context.valid = false;
1913
+ if (onlyCheckValid) {
1914
+ return context.valid;
1915
+ }
1916
+ }
1917
+ }
1862
1918
  for (const name in fields) {
1863
1919
  const field = fields[name];
1864
1920
  if (field) {
@@ -1874,25 +1930,34 @@ function createFormControl(props = {}) {
1874
1930
  ..._names.disabled,
1875
1931
  ..._names.readonly,
1876
1932
  ]);
1877
- const fieldError = await validateField(field, skipValidationFields, _formValues, shouldDisplayAllAssociatedErrors, _options.shouldUseNativeValidation && !shouldOnlyCheckValid, isFieldArrayRoot);
1933
+ const fieldError = await validateField(field, skipValidationFields, _formValues, shouldDisplayAllAssociatedErrors, _options.shouldUseNativeValidation && !onlyCheckValid, isFieldArrayRoot);
1878
1934
  if (isPromiseFunction && _proxyFormState.validatingFields) {
1879
1935
  _updateIsValidating([_f.name]);
1880
1936
  }
1881
1937
  if (fieldError[_f.name]) {
1882
1938
  context.valid = false;
1883
- if (shouldOnlyCheckValid || props.shouldUseNativeValidation) {
1939
+ if (onlyCheckValid) {
1884
1940
  break;
1885
1941
  }
1886
1942
  }
1887
- !shouldOnlyCheckValid &&
1943
+ !onlyCheckValid &&
1888
1944
  (get(fieldError, _f.name)
1889
1945
  ? isFieldArrayRoot
1890
1946
  ? updateFieldArrayRootError(_formState.errors, fieldError, _f.name)
1891
1947
  : set(_formState.errors, _f.name, fieldError[_f.name])
1892
1948
  : unset(_formState.errors, _f.name));
1949
+ if (props.shouldUseNativeValidation && fieldError[_f.name]) {
1950
+ break;
1951
+ }
1893
1952
  }
1894
1953
  !isEmptyObject(fieldValue) &&
1895
- (await executeBuiltInValidation(fieldValue, shouldOnlyCheckValid, context));
1954
+ (await executeBuiltInValidation({
1955
+ context,
1956
+ onlyCheckValid,
1957
+ fields: fieldValue,
1958
+ name: name,
1959
+ eventType,
1960
+ }));
1896
1961
  }
1897
1962
  }
1898
1963
  return context.valid;
@@ -2136,6 +2201,7 @@ function createFormControl(props = {}) {
2136
2201
  const isBlurEvent = event.type === EVENTS.BLUR || event.type === EVENTS.FOCUS_OUT;
2137
2202
  const isFocusEvent = event.type === EVENTS.FOCUS || event.type === EVENTS.FOCUS_IN;
2138
2203
  const shouldSkipValidation = (!hasValidation(field._f) &&
2204
+ !props.validate &&
2139
2205
  !_options.resolver &&
2140
2206
  !get(_formState.errors, name) &&
2141
2207
  !field._f.deps) ||
@@ -2173,6 +2239,12 @@ function createFormControl(props = {}) {
2173
2239
  return (shouldRender &&
2174
2240
  _subjects.state.next({ name, ...(watched ? {} : fieldState) }));
2175
2241
  }
2242
+ if (!_options.resolver && props.validate) {
2243
+ await validateForm({
2244
+ name: name,
2245
+ eventType: event.type,
2246
+ });
2247
+ }
2176
2248
  !isBlurEvent && watched && _subjects.state.next({ ..._formState });
2177
2249
  if (_options.resolver) {
2178
2250
  const { errors } = await _runSchema([name]);
@@ -2202,7 +2274,12 @@ function createFormControl(props = {}) {
2202
2274
  }
2203
2275
  else if (_proxyFormState.isValid ||
2204
2276
  _proxySubscribeFormState.isValid) {
2205
- isValid = await executeBuiltInValidation(_fields, true);
2277
+ isValid = await executeBuiltInValidation({
2278
+ fields: _fields,
2279
+ onlyCheckValid: true,
2280
+ name: name,
2281
+ eventType: event.type,
2282
+ });
2206
2283
  }
2207
2284
  }
2208
2285
  }
@@ -2235,12 +2312,19 @@ function createFormControl(props = {}) {
2235
2312
  else if (name) {
2236
2313
  validationResult = (await Promise.all(fieldNames.map(async (fieldName) => {
2237
2314
  const field = get(_fields, fieldName);
2238
- return await executeBuiltInValidation(field && field._f ? { [fieldName]: field } : field);
2315
+ return await executeBuiltInValidation({
2316
+ fields: field && field._f ? { [fieldName]: field } : field,
2317
+ eventType: EVENTS.TRIGGER,
2318
+ });
2239
2319
  }))).every(Boolean);
2240
2320
  !(!validationResult && !_formState.isValid) && _setValid();
2241
2321
  }
2242
2322
  else {
2243
- validationResult = isValid = await executeBuiltInValidation(_fields);
2323
+ validationResult = isValid = await executeBuiltInValidation({
2324
+ fields: _fields,
2325
+ name,
2326
+ eventType: EVENTS.TRIGGER,
2327
+ });
2244
2328
  }
2245
2329
  _subjects.state.next({
2246
2330
  ...(!isString(name) ||
@@ -2547,14 +2631,17 @@ function createFormControl(props = {}) {
2547
2631
  fieldValues = cloneObject(values);
2548
2632
  }
2549
2633
  else {
2550
- await executeBuiltInValidation(_fields);
2634
+ await executeBuiltInValidation({
2635
+ fields: _fields,
2636
+ eventType: EVENTS.SUBMIT,
2637
+ });
2551
2638
  }
2552
2639
  if (_names.disabled.size) {
2553
2640
  for (const name of _names.disabled) {
2554
2641
  unset(fieldValues, name);
2555
2642
  }
2556
2643
  }
2557
- unset(_formState.errors, 'root');
2644
+ unset(_formState.errors, ROOT_ERROR_TYPE);
2558
2645
  if (isEmptyObject(_formState.errors)) {
2559
2646
  _subjects.state.next({
2560
2647
  errors: {},