@bombillazo/rhf-plus 7.62.0-plus.6 → 7.63.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.
@@ -1 +1 @@
1
- {"version":3,"file":"createFormControl.d.ts","sourceRoot":"","sources":["../../src/logic/createFormControl.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAaV,WAAW,EACX,YAAY,EAgBZ,YAAY,EAIZ,aAAa,EAUd,MAAM,UAAU,CAAC;AAuDlB,wBAAgB,iBAAiB,CAC/B,YAAY,SAAS,WAAW,GAAG,WAAW,EAC9C,QAAQ,GAAG,GAAG,EACd,kBAAkB,GAAG,YAAY,EACjC,SAAS,SAAS,YAAY,GAAG,GAAG,EAEpC,KAAK,GAAE,YAAY,CACjB,YAAY,EACZ,QAAQ,EACR,kBAAkB,EAClB,SAAS,CACL,GACL,IAAI,CACL,aAAa,CAAC,YAAY,EAAE,QAAQ,EAAE,kBAAkB,EAAE,SAAS,CAAC,EACpE,WAAW,CACZ,GAAG;IACF,WAAW,EAAE,IAAI,CACf,aAAa,CAAC,YAAY,EAAE,QAAQ,EAAE,kBAAkB,EAAE,SAAS,CAAC,EACpE,WAAW,CACZ,CAAC;CACH,CAipDA"}
1
+ {"version":3,"file":"createFormControl.d.ts","sourceRoot":"","sources":["../../src/logic/createFormControl.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAaV,WAAW,EACX,YAAY,EAiBZ,YAAY,EAIZ,aAAa,EAUd,MAAM,UAAU,CAAC;AAyDlB,wBAAgB,iBAAiB,CAC/B,YAAY,SAAS,WAAW,GAAG,WAAW,EAC9C,QAAQ,GAAG,GAAG,EACd,kBAAkB,GAAG,YAAY,EACjC,SAAS,SAAS,YAAY,GAAG,GAAG,EAEpC,KAAK,GAAE,YAAY,CACjB,YAAY,EACZ,QAAQ,EACR,kBAAkB,EAClB,SAAS,CACL,GACL,IAAI,CACL,aAAa,CAAC,YAAY,EAAE,QAAQ,EAAE,kBAAkB,EAAE,SAAS,CAAC,EACpE,WAAW,CACZ,GAAG;IACF,WAAW,EAAE,IAAI,CACf,aAAa,CAAC,YAAY,EAAE,QAAQ,EAAE,kBAAkB,EAAE,SAAS,CAAC,EACpE,WAAW,CACZ,CAAC;CACH,CA+vDA"}
@@ -1,3 +1,4 @@
1
- declare const _default: <T>(defaultValues: T, formValues: T) => Record<Extract<keyof T, string>, boolean | Record<string, any>>;
2
- export default _default;
1
+ declare function markFieldsDirty<T>(data: T, fields?: Record<string, any>): Record<string, any>;
2
+ export default function getDirtyFields<T>(data: T, formValues: T, dirtyFieldsFromValues?: Record<Extract<keyof T, string>, ReturnType<typeof markFieldsDirty> | boolean>): Record<Extract<keyof T, string>, boolean | Record<string, any>>;
3
+ export {};
3
4
  //# sourceMappingURL=getDirtyFields.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"getDirtyFields.d.ts","sourceRoot":"","sources":["../../src/logic/getDirtyFields.ts"],"names":[],"mappings":"yBAkEgB,CAAC,EAAE,eAAe,CAAC,EAAE,YAAY,CAAC;AAAlD,wBAKI"}
1
+ {"version":3,"file":"getDirtyFields.d.ts","sourceRoot":"","sources":["../../src/logic/getDirtyFields.ts"],"names":[],"mappings":"AAWA,iBAAS,eAAe,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,MAAM,GAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAM,uBAWpE;AAED,MAAM,CAAC,OAAO,UAAU,cAAc,CAAC,CAAC,EACtC,IAAI,EAAE,CAAC,EACP,UAAU,EAAE,CAAC,EACb,qBAAqB,CAAC,EAAE,MAAM,CAC5B,OAAO,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,EACxB,UAAU,CAAC,OAAO,eAAe,CAAC,GAAG,OAAO,CAC7C,mEA0BF"}
@@ -1 +1 @@
1
- {"version":3,"file":"getValidateError.d.ts","sourceRoot":"","sources":["../../src/logic/getValidateError.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAW,GAAG,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAIzE,MAAM,CAAC,OAAO,UAAU,gBAAgB,CACtC,MAAM,EAAE,cAAc,EACtB,GAAG,EAAE,GAAG,EACR,IAAI,SAAa,GAChB,UAAU,GAAG,IAAI,CAYnB"}
1
+ {"version":3,"file":"getValidateError.d.ts","sourceRoot":"","sources":["../../src/logic/getValidateError.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,GAAG,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAIhE,MAAM,CAAC,OAAO,UAAU,gBAAgB,CACtC,MAAM,EAAE,cAAc,EACtB,GAAG,EAAE,GAAG,EACR,IAAI,SAAa,GAChB,UAAU,GAAG,IAAI,CAYnB"}
@@ -1,4 +1,4 @@
1
1
  import type { Field, FieldValues, InternalFieldErrors, InternalNameSet } from '../types';
2
- declare const _default: <T extends FieldValues>(field: Field, disabledFieldNames: InternalNameSet, formValues: T, validateAllFieldCriteria: boolean, shouldUseNativeValidation?: boolean, isFieldArray?: boolean) => Promise<InternalFieldErrors>;
2
+ declare const _default: <T extends FieldValues>(field: Field, skippedFieldNames: InternalNameSet, formValues: T, validateAllFieldCriteria: boolean, shouldUseNativeValidation?: boolean, isFieldArray?: boolean) => Promise<InternalFieldErrors>;
3
3
  export default _default;
4
4
  //# sourceMappingURL=validateField.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"validateField.d.ts","sourceRoot":"","sources":["../../src/logic/validateField.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,KAAK,EAEL,WAAW,EACX,mBAAmB,EACnB,eAAe,EAKhB,MAAM,UAAU,CAAC;yBAsBI,CAAC,SAAS,WAAW,EACzC,OAAO,KAAK,EACZ,oBAAoB,eAAe,EACnC,YAAY,CAAC,EACb,0BAA0B,OAAO,EACjC,4BAA4B,OAAO,EACnC,eAAe,OAAO,KACrB,OAAO,CAAC,mBAAmB,CAAC;AAP/B,wBAoQE"}
1
+ {"version":3,"file":"validateField.d.ts","sourceRoot":"","sources":["../../src/logic/validateField.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,KAAK,EAEL,WAAW,EACX,mBAAmB,EACnB,eAAe,EAKhB,MAAM,UAAU,CAAC;yBAsBI,CAAC,SAAS,WAAW,EACzC,OAAO,KAAK,EACZ,mBAAmB,eAAe,EAClC,YAAY,CAAC,EACb,0BAA0B,OAAO,EACjC,4BAA4B,OAAO,EACnC,eAAe,OAAO,KACrB,OAAO,CAAC,mBAAmB,CAAC;AAP/B,wBAqQE"}
@@ -178,6 +178,26 @@ function deepMerge(target, source) {
178
178
  return target;
179
179
  }
180
180
 
181
+ function extractFormValues(fieldsState, formValues) {
182
+ const values = {};
183
+ for (const key in fieldsState) {
184
+ if (fieldsState.hasOwnProperty(key)) {
185
+ const fieldState = fieldsState[key];
186
+ const fieldValue = formValues[key];
187
+ if (fieldState && isObject(fieldState) && fieldValue) {
188
+ const nestedFieldsState = extractFormValues(fieldState, fieldValue);
189
+ if (isObject(nestedFieldsState)) {
190
+ values[key] = nestedFieldsState;
191
+ }
192
+ }
193
+ else if (fieldsState[key]) {
194
+ values[key] = fieldValue;
195
+ }
196
+ }
197
+ }
198
+ return values;
199
+ }
200
+
181
201
  var isKey = (value) => /^\w*$/.test(value);
182
202
 
183
203
  var isUndefined = (val) => val === undefined;
@@ -321,46 +341,40 @@ var objectHasFunction = (data) => {
321
341
  return false;
322
342
  };
323
343
 
344
+ function isTraversable(value) {
345
+ return Array.isArray(value) || (isObject(value) && !objectHasFunction(value));
346
+ }
324
347
  function markFieldsDirty(data, fields = {}) {
325
- const isParentNodeArray = Array.isArray(data);
326
- if (isObject(data) || isParentNodeArray) {
327
- for (const key in data) {
328
- if (Array.isArray(data[key]) ||
329
- (isObject(data[key]) && !objectHasFunction(data[key]))) {
330
- fields[key] = Array.isArray(data[key]) ? [] : {};
331
- markFieldsDirty(data[key], fields[key]);
332
- }
333
- else if (!isNullOrUndefined(data[key])) {
334
- fields[key] = true;
335
- }
348
+ for (const key in data) {
349
+ if (isTraversable(data[key])) {
350
+ fields[key] = Array.isArray(data[key]) ? [] : {};
351
+ markFieldsDirty(data[key], fields[key]);
352
+ }
353
+ else if (!isNullOrUndefined(data[key])) {
354
+ fields[key] = true;
336
355
  }
337
356
  }
338
357
  return fields;
339
358
  }
340
- function getDirtyFieldsFromDefaultValues(data, formValues, dirtyFieldsFromValues) {
341
- const isParentNodeArray = Array.isArray(data);
342
- if (isObject(data) || isParentNodeArray) {
343
- for (const key in data) {
344
- if (Array.isArray(data[key]) ||
345
- (isObject(data[key]) && !objectHasFunction(data[key]))) {
346
- if (isUndefined(formValues) ||
347
- isPrimitive(dirtyFieldsFromValues[key])) {
348
- dirtyFieldsFromValues[key] = Array.isArray(data[key])
349
- ? markFieldsDirty(data[key], [])
350
- : { ...markFieldsDirty(data[key]) };
351
- }
352
- else {
353
- getDirtyFieldsFromDefaultValues(data[key], isNullOrUndefined(formValues) ? {} : formValues[key], dirtyFieldsFromValues[key]);
354
- }
359
+ function getDirtyFields(data, formValues, dirtyFieldsFromValues) {
360
+ if (!dirtyFieldsFromValues) {
361
+ dirtyFieldsFromValues = markFieldsDirty(formValues);
362
+ }
363
+ for (const key in data) {
364
+ if (isTraversable(data[key])) {
365
+ if (isUndefined(formValues) || isPrimitive(dirtyFieldsFromValues[key])) {
366
+ dirtyFieldsFromValues[key] = markFieldsDirty(data[key], Array.isArray(data[key]) ? [] : {});
355
367
  }
356
368
  else {
357
- dirtyFieldsFromValues[key] = !deepEqual(data[key], formValues[key]);
369
+ getDirtyFields(data[key], isNullOrUndefined(formValues) ? {} : formValues[key], dirtyFieldsFromValues[key]);
358
370
  }
359
371
  }
372
+ else {
373
+ dirtyFieldsFromValues[key] = !deepEqual(data[key], formValues[key]);
374
+ }
360
375
  }
361
376
  return dirtyFieldsFromValues;
362
377
  }
363
- var getDirtyFields = (defaultValues, formValues) => getDirtyFieldsFromDefaultValues(defaultValues, formValues, markFieldsDirty(formValues));
364
378
 
365
379
  var getEventValue = (event) => isObject(event) && event.target
366
380
  ? isCheckBoxInput(event.target)
@@ -643,10 +657,10 @@ var getValueAndMessage = (validationData) => isObject(validationData) && !isRege
643
657
  message: '',
644
658
  };
645
659
 
646
- var validateField = async (field, disabledFieldNames, formValues, validateAllFieldCriteria, shouldUseNativeValidation, isFieldArray) => {
660
+ var validateField = async (field, skippedFieldNames, formValues, validateAllFieldCriteria, shouldUseNativeValidation, isFieldArray) => {
647
661
  const { ref, refs, required, maxLength, minLength, min, max, pattern, validate, name, valueAsNumber, mount, } = field._f;
648
662
  const inputValue = get(formValues, name);
649
- if (!mount || disabledFieldNames.has(name)) {
663
+ if (!mount || skippedFieldNames.has(name)) {
650
664
  return {};
651
665
  }
652
666
  const inputRef = refs ? refs[0] : ref;
@@ -835,6 +849,7 @@ const defaultOptions = {
835
849
  mode: VALIDATION_MODE.onSubmit,
836
850
  reValidateMode: VALIDATION_MODE.onChange,
837
851
  shouldFocusError: true,
852
+ shouldSkipReadOnlyValidation: false,
838
853
  };
839
854
  function createFormControl(props = {}) {
840
855
  let _options = {
@@ -879,6 +894,7 @@ function createFormControl(props = {}) {
879
894
  let _names = {
880
895
  mount: new Set(),
881
896
  disabled: new Set(),
897
+ readonly: new Set(),
882
898
  unMount: new Set(),
883
899
  array: new Set(),
884
900
  watch: new Set(),
@@ -1144,11 +1160,16 @@ function createFormControl(props = {}) {
1144
1160
  const isFieldArrayRoot = _names.array.has(_f.name);
1145
1161
  const isPromiseFunction = field._f && hasPromiseValidation(field._f);
1146
1162
  if (isPromiseFunction && _proxyFormState.validatingFields) {
1147
- _updateIsValidating([name], true);
1163
+ _updateIsValidating([_f.name], true);
1148
1164
  }
1149
- const fieldError = await validateField(field, _names.disabled, _formValues, shouldDisplayAllAssociatedErrors, _options.shouldUseNativeValidation && !shouldOnlyCheckValid, isFieldArrayRoot);
1165
+ // Combine disabled and readonly field names for validation skipping
1166
+ const skipValidationFields = new Set([
1167
+ ..._names.disabled,
1168
+ ..._names.readonly,
1169
+ ]);
1170
+ const fieldError = await validateField(field, skipValidationFields, _formValues, shouldDisplayAllAssociatedErrors, _options.shouldUseNativeValidation && !shouldOnlyCheckValid, isFieldArrayRoot);
1150
1171
  if (isPromiseFunction && _proxyFormState.validatingFields) {
1151
- _updateIsValidating([name]);
1172
+ _updateIsValidating([_f.name]);
1152
1173
  }
1153
1174
  if (fieldError[_f.name]) {
1154
1175
  context.valid = false;
@@ -1352,6 +1373,36 @@ function createFormControl(props = {}) {
1352
1373
  }
1353
1374
  return;
1354
1375
  }
1376
+ // Check if field is readonly and should skip validation (only when flag is enabled)
1377
+ if (_options.shouldSkipReadOnlyValidation && target && target.readOnly) {
1378
+ // Add to readonly fields set for validation skipping
1379
+ _names.readonly.add(name);
1380
+ // For readonly fields, we still want to update the form values
1381
+ // but skip validation (similar to disabled fields behavior)
1382
+ const fieldValue = target.type
1383
+ ? getFieldValue(field._f)
1384
+ : getEventValue(event);
1385
+ const isBlurEvent = event.type === EVENTS.BLUR || event.type === EVENTS.FOCUS_OUT;
1386
+ const isFocusEvent = event.type === EVENTS.FOCUS || event.type === EVENTS.FOCUS_IN;
1387
+ const watched = isWatched(name, _names, isBlurEvent || isFocusEvent);
1388
+ // Update form values but skip validation and error handling
1389
+ set(_formValues, name, fieldValue);
1390
+ // Update touch and dirty state
1391
+ const fieldState = updateTouchAndDirty(name, fieldValue, isBlurEvent, isFocusEvent, !isBlurEvent);
1392
+ const shouldRender = !isEmptyObject(fieldState) || watched;
1393
+ !isBlurEvent &&
1394
+ _subjects.state.next({
1395
+ name,
1396
+ type: event.type,
1397
+ values: cloneObject(_formValues),
1398
+ });
1399
+ return (shouldRender &&
1400
+ _subjects.state.next({ name, ...(watched ? {} : fieldState) }));
1401
+ }
1402
+ else if (_options.shouldSkipReadOnlyValidation) {
1403
+ // Remove from readonly fields set if not readonly anymore (only when flag is enabled)
1404
+ _names.readonly.delete(name);
1405
+ }
1355
1406
  let error;
1356
1407
  let isValid;
1357
1408
  const fieldValue = target.type
@@ -1411,7 +1462,12 @@ function createFormControl(props = {}) {
1411
1462
  }
1412
1463
  else {
1413
1464
  _updateIsValidating([name], true);
1414
- error = (await validateField(field, _names.disabled, _formValues, shouldDisplayAllAssociatedErrors, _options.shouldUseNativeValidation))[name];
1465
+ // Combine disabled and readonly field names for validation skipping
1466
+ const skipValidationFields = new Set([
1467
+ ..._names.disabled,
1468
+ ..._names.readonly,
1469
+ ]);
1470
+ error = (await validateField(field, skipValidationFields, _formValues, shouldDisplayAllAssociatedErrors, _options.shouldUseNativeValidation, false))[name];
1415
1471
  _updateIsValidating([name]);
1416
1472
  _updateIsFieldValueUpdated(fieldValue);
1417
1473
  if (isFieldValueUpdated) {
@@ -1426,6 +1482,7 @@ function createFormControl(props = {}) {
1426
1482
  }
1427
1483
  if (isFieldValueUpdated) {
1428
1484
  field._f.deps &&
1485
+ (!Array.isArray(field._f.deps) || field._f.deps.length > 0) &&
1429
1486
  trigger(field._f.deps);
1430
1487
  shouldRenderByError(name, isValid, error, fieldState);
1431
1488
  }
@@ -1473,10 +1530,13 @@ function createFormControl(props = {}) {
1473
1530
  iterateFieldsByAction(_fields, _focusInput, name ? fieldNames : _names.mount);
1474
1531
  return validationResult;
1475
1532
  };
1476
- const getValues = (fieldNames) => {
1477
- const values = {
1533
+ const getValues = (fieldNames, config) => {
1534
+ let values = {
1478
1535
  ...(_state.mount ? _formValues : _defaultValues),
1479
1536
  };
1537
+ if (config) {
1538
+ values = extractFormValues(config.dirtyFields ? _formState.dirtyFields : _formState.touchedFields, values);
1539
+ }
1480
1540
  return isUndefined(fieldNames)
1481
1541
  ? values
1482
1542
  : isString(fieldNames)
@@ -1662,6 +1722,13 @@ function createFormControl(props = {}) {
1662
1722
  },
1663
1723
  });
1664
1724
  updateValidAndValue(name, false, undefined, fieldRef);
1725
+ // Check if field is readonly and should skip validation (only when flag is enabled)
1726
+ if (_options.shouldSkipReadOnlyValidation &&
1727
+ fieldRef &&
1728
+ 'readOnly' in fieldRef &&
1729
+ fieldRef.readOnly) {
1730
+ _names.readonly.add(name);
1731
+ }
1665
1732
  }
1666
1733
  else {
1667
1734
  field = get(_fields, name, {});
@@ -1862,6 +1929,7 @@ function createFormControl(props = {}) {
1862
1929
  unMount: new Set(),
1863
1930
  array: new Set(),
1864
1931
  disabled: new Set(),
1932
+ readonly: new Set(),
1865
1933
  watch: new Set(),
1866
1934
  watchAll: false,
1867
1935
  focus: '',
@@ -1961,6 +2029,28 @@ function createFormControl(props = {}) {
1961
2029
  });
1962
2030
  }
1963
2031
  };
2032
+ const _updateReadonlyFieldTracking = () => {
2033
+ // Re-evaluate all registered fields and update readonly tracking
2034
+ // based on current shouldSkipReadOnlyValidation flag and field readonly state
2035
+ Object.keys(_fields).forEach((fieldName) => {
2036
+ const field = get(_fields, fieldName);
2037
+ if (field && field._f) {
2038
+ // Get the actual DOM element reference
2039
+ const fieldRef = field._f.refs ? field._f.refs[0] : field._f.ref;
2040
+ if (fieldRef && 'readOnly' in fieldRef) {
2041
+ const isFieldReadonly = Boolean(fieldRef.readOnly);
2042
+ const shouldTrackAsReadonly = _options.shouldSkipReadOnlyValidation && isFieldReadonly;
2043
+ // Update readonly tracking set
2044
+ if (shouldTrackAsReadonly) {
2045
+ _names.readonly.add(fieldName);
2046
+ }
2047
+ else {
2048
+ _names.readonly.delete(fieldName);
2049
+ }
2050
+ }
2051
+ }
2052
+ });
2053
+ };
1964
2054
  const setMetadata = (metadata) => {
1965
2055
  let _metadata;
1966
2056
  if (!metadata) {
@@ -2005,6 +2095,7 @@ function createFormControl(props = {}) {
2005
2095
  _removeUnmounted,
2006
2096
  _disableForm,
2007
2097
  _updateIsLoading,
2098
+ _updateReadonlyFieldTracking,
2008
2099
  _subjects,
2009
2100
  _proxyFormState,
2010
2101
  get _fields() {