react-hook-form 7.39.4 → 7.40.0-next.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.
Files changed (48) hide show
  1. package/dist/__typetest__/__fixtures__/pathString.d.ts +2 -2
  2. package/dist/__typetest__/__fixtures__/pathString.d.ts.map +1 -1
  3. package/dist/__typetest__/__fixtures__/traversable.d.ts +3 -3
  4. package/dist/__typetest__/__fixtures__/traversable.d.ts.map +1 -1
  5. package/dist/__typetest__/__fixtures__/tuple.d.ts +2 -2
  6. package/dist/__typetest__/__fixtures__/tuple.d.ts.map +1 -1
  7. package/dist/index.cjs.js +1 -1
  8. package/dist/index.cjs.js.map +1 -1
  9. package/dist/index.esm.mjs +62 -39
  10. package/dist/index.esm.mjs.map +1 -1
  11. package/dist/index.umd.js +1 -1
  12. package/dist/index.umd.js.map +1 -1
  13. package/dist/logic/createFormControl.d.ts.map +1 -1
  14. package/dist/logic/getCheckboxValue.d.ts +1 -1
  15. package/dist/logic/getCheckboxValue.d.ts.map +1 -1
  16. package/dist/logic/getRadioValue.d.ts +1 -1
  17. package/dist/logic/getRadioValue.d.ts.map +1 -1
  18. package/dist/types/controller.d.ts +5 -5
  19. package/dist/types/controller.d.ts.map +1 -1
  20. package/dist/types/errors.d.ts +8 -8
  21. package/dist/types/errors.d.ts.map +1 -1
  22. package/dist/types/events.d.ts +1 -1
  23. package/dist/types/events.d.ts.map +1 -1
  24. package/dist/types/fieldArray.d.ts +13 -13
  25. package/dist/types/fieldArray.d.ts.map +1 -1
  26. package/dist/types/fields.d.ts +10 -10
  27. package/dist/types/fields.d.ts.map +1 -1
  28. package/dist/types/form.d.ts +56 -52
  29. package/dist/types/form.d.ts.map +1 -1
  30. package/dist/types/path/common.d.ts +32 -32
  31. package/dist/types/path/common.d.ts.map +1 -1
  32. package/dist/types/path/eager.d.ts +11 -11
  33. package/dist/types/path/eager.d.ts.map +1 -1
  34. package/dist/types/resolvers.d.ts +4 -4
  35. package/dist/types/resolvers.d.ts.map +1 -1
  36. package/dist/types/utils.d.ts +13 -13
  37. package/dist/types/utils.d.ts.map +1 -1
  38. package/dist/types/validator.d.ts +6 -6
  39. package/dist/types/validator.d.ts.map +1 -1
  40. package/dist/useFieldArray.d.ts.map +1 -1
  41. package/dist/useForm.d.ts.map +1 -1
  42. package/dist/useFormState.d.ts.map +1 -1
  43. package/dist/useSubscribe.d.ts +2 -2
  44. package/dist/useSubscribe.d.ts.map +1 -1
  45. package/dist/utils/createSubject.d.ts +3 -3
  46. package/dist/utils/createSubject.d.ts.map +1 -1
  47. package/dist/utils/isHTMLElement.d.ts.map +1 -1
  48. package/package.json +3 -3
@@ -173,7 +173,7 @@ function useSubscribe(props) {
173
173
  React.useEffect(() => {
174
174
  const subscription = !props.disabled &&
175
175
  _props.current.subject.subscribe({
176
- next: _props.current.callback,
176
+ next: _props.current.next,
177
177
  });
178
178
  return () => {
179
179
  subscription && subscription.unsubscribe();
@@ -228,21 +228,28 @@ function useFormState(props) {
228
228
  _name.current = name;
229
229
  useSubscribe({
230
230
  disabled,
231
- callback: React.useCallback((value) => _mounted.current &&
231
+ next: (value) => _mounted.current &&
232
232
  shouldSubscribeByName(_name.current, value.name, exact) &&
233
233
  shouldRenderFormState(value, _localProxyFormState.current) &&
234
234
  updateFormState({
235
235
  ...control._formState,
236
236
  ...value,
237
- }), [control, exact]),
237
+ }),
238
238
  subject: control._subjects.state,
239
239
  });
240
240
  React.useEffect(() => {
241
241
  _mounted.current = true;
242
+ const isDirty = control._proxyFormState.isDirty && control._getDirty();
243
+ if (isDirty !== control._formState.isDirty) {
244
+ control._subjects.state.next({
245
+ isDirty,
246
+ });
247
+ }
248
+ control._updateValid();
242
249
  return () => {
243
250
  _mounted.current = false;
244
251
  };
245
- }, []);
252
+ }, [control]);
246
253
  return getProxyFormState(formState, control, _localProxyFormState.current, false);
247
254
  }
248
255
 
@@ -322,7 +329,7 @@ function useWatch(props) {
322
329
  useSubscribe({
323
330
  disabled,
324
331
  subject: control._subjects.watch,
325
- callback: React.useCallback((formState) => {
332
+ next: (formState) => {
326
333
  if (shouldSubscribeByName(_name.current, formState.name, exact)) {
327
334
  const fieldValues = generateWatchOutput(_name.current, control._names, formState.values || control._formValues);
328
335
  updateValue(isUndefined(_name.current) || !isUndefined(fieldValues)
@@ -331,7 +338,7 @@ function useWatch(props) {
331
338
  ? defaultValue
332
339
  : fieldValues);
333
340
  }
334
- }, [control, exact, defaultValue]),
341
+ },
335
342
  });
336
343
  const [value, updateValue] = React.useState(isUndefined(defaultValue)
337
344
  ? control._getWatch(name)
@@ -979,17 +986,16 @@ function useFieldArray(props) {
979
986
  control._names.array.add(name);
980
987
  props.rules &&
981
988
  control.register(name, props.rules);
982
- const callback = React.useCallback(({ values, name: fieldArrayName, }) => {
983
- if (fieldArrayName === _name.current || !fieldArrayName) {
984
- const fieldValues = get(values, _name.current);
985
- if (Array.isArray(fieldValues)) {
986
- setFields(fieldValues);
987
- ids.current = fieldValues.map(generateId);
988
- }
989
- }
990
- }, []);
991
989
  useSubscribe({
992
- callback,
990
+ next: ({ values, name: fieldArrayName, }) => {
991
+ if (fieldArrayName === _name.current || !fieldArrayName) {
992
+ const fieldValues = get(values, _name.current);
993
+ if (Array.isArray(fieldValues)) {
994
+ setFields(fieldValues);
995
+ ids.current = fieldValues.map(generateId);
996
+ }
997
+ }
998
+ },
993
999
  subject: control._subjects.array,
994
1000
  });
995
1001
  const updateValues = React.useCallback((updatedFieldArrayValues) => {
@@ -1204,8 +1210,8 @@ function deepEqual(object1, object2) {
1204
1210
 
1205
1211
  var isHTMLElement = (value) => {
1206
1212
  const owner = value ? value.ownerDocument : 0;
1207
- const ElementClass = owner && owner.defaultView ? owner.defaultView.HTMLElement : HTMLElement;
1208
- return value instanceof ElementClass;
1213
+ return (value instanceof
1214
+ (owner && owner.defaultView ? owner.defaultView.HTMLElement : HTMLElement));
1209
1215
  };
1210
1216
 
1211
1217
  var isMultipleSelect = (element) => element.type === `select-multiple`;
@@ -1403,7 +1409,9 @@ function createFormControl(props = {}) {
1403
1409
  errors: {},
1404
1410
  };
1405
1411
  let _fields = {};
1406
- let _defaultValues = cloneObject(_options.defaultValues) || {};
1412
+ let _defaultValues = isObject(_options.defaultValues)
1413
+ ? cloneObject(_options.defaultValues) || {}
1414
+ : {};
1407
1415
  let _formValues = _options.shouldUnregister
1408
1416
  ? {}
1409
1417
  : cloneObject(_defaultValues);
@@ -1509,37 +1517,39 @@ function createFormControl(props = {}) {
1509
1517
  }
1510
1518
  };
1511
1519
  const updateTouchAndDirty = (name, fieldValue, isBlurEvent, shouldDirty, shouldRender) => {
1512
- let isFieldDirty = false;
1520
+ let shouldUpdateField = false;
1521
+ let isPreviousDirty = false;
1513
1522
  const output = {
1514
1523
  name,
1515
1524
  };
1516
- const isPreviousFieldTouched = get(_formState.touchedFields, name);
1517
1525
  if (_proxyFormState.isDirty) {
1518
- const isPreviousFormDirty = _formState.isDirty;
1526
+ isPreviousDirty = _formState.isDirty;
1519
1527
  _formState.isDirty = output.isDirty = _getDirty();
1520
- isFieldDirty = isPreviousFormDirty !== output.isDirty;
1528
+ shouldUpdateField = isPreviousDirty !== output.isDirty;
1521
1529
  }
1522
1530
  if (_proxyFormState.dirtyFields && (!isBlurEvent || shouldDirty)) {
1523
- const isPreviousFieldDirty = get(_formState.dirtyFields, name);
1531
+ isPreviousDirty = get(_formState.dirtyFields, name);
1524
1532
  const isCurrentFieldPristine = deepEqual(get(_defaultValues, name), fieldValue);
1525
1533
  isCurrentFieldPristine
1526
1534
  ? unset(_formState.dirtyFields, name)
1527
1535
  : set(_formState.dirtyFields, name, true);
1528
1536
  output.dirtyFields = _formState.dirtyFields;
1529
- isFieldDirty =
1530
- isFieldDirty ||
1531
- isPreviousFieldDirty !== get(_formState.dirtyFields, name);
1537
+ shouldUpdateField =
1538
+ shouldUpdateField || isPreviousDirty !== !isCurrentFieldPristine;
1532
1539
  }
1533
- if (isBlurEvent && !isPreviousFieldTouched) {
1534
- set(_formState.touchedFields, name, isBlurEvent);
1535
- output.touchedFields = _formState.touchedFields;
1536
- isFieldDirty =
1537
- isFieldDirty ||
1538
- (_proxyFormState.touchedFields &&
1539
- isPreviousFieldTouched !== isBlurEvent);
1540
+ if (isBlurEvent) {
1541
+ const isPreviousFieldTouched = get(_formState.touchedFields, name);
1542
+ if (!isPreviousFieldTouched) {
1543
+ set(_formState.touchedFields, name, isBlurEvent);
1544
+ output.touchedFields = _formState.touchedFields;
1545
+ shouldUpdateField =
1546
+ shouldUpdateField ||
1547
+ (_proxyFormState.touchedFields &&
1548
+ isPreviousFieldTouched !== isBlurEvent);
1549
+ }
1540
1550
  }
1541
- isFieldDirty && shouldRender && _subjects.state.next(output);
1542
- return isFieldDirty ? output : {};
1551
+ shouldUpdateField && shouldRender && _subjects.state.next(output);
1552
+ return shouldUpdateField ? output : {};
1543
1553
  };
1544
1554
  const shouldRenderByError = (name, isValid, error, fieldState) => {
1545
1555
  const previousFieldError = get(_formState.errors, name);
@@ -2165,6 +2175,11 @@ function createFormControl(props = {}) {
2165
2175
  }
2166
2176
  }
2167
2177
  };
2178
+ if (isFunction(_options.defaultValues)) {
2179
+ _options.defaultValues().then((values) => {
2180
+ reset(values, _options.resetOptions);
2181
+ });
2182
+ }
2168
2183
  return {
2169
2184
  control: {
2170
2185
  register,
@@ -2178,6 +2193,7 @@ function createFormControl(props = {}) {
2178
2193
  _removeUnmounted,
2179
2194
  _updateFieldArray,
2180
2195
  _getFieldArray,
2196
+ _reset,
2181
2197
  _subjects,
2182
2198
  _proxyFormState,
2183
2199
  get _fields() {
@@ -2275,7 +2291,9 @@ function useForm(props = {}) {
2275
2291
  dirtyFields: {},
2276
2292
  touchedFields: {},
2277
2293
  errors: {},
2278
- defaultValues: props.defaultValues,
2294
+ defaultValues: isFunction(props.defaultValues)
2295
+ ? undefined
2296
+ : props.defaultValues,
2279
2297
  });
2280
2298
  if (!_formControl.current) {
2281
2299
  _formControl.current = {
@@ -2287,7 +2305,7 @@ function useForm(props = {}) {
2287
2305
  control._options = props;
2288
2306
  useSubscribe({
2289
2307
  subject: control._subjects.state,
2290
- callback: React.useCallback((value) => {
2308
+ next: (value) => {
2291
2309
  if (shouldRenderFormState(value, control._proxyFormState, true)) {
2292
2310
  control._formState = {
2293
2311
  ...control._formState,
@@ -2295,7 +2313,7 @@ function useForm(props = {}) {
2295
2313
  };
2296
2314
  updateFormState({ ...control._formState });
2297
2315
  }
2298
- }, [control]),
2316
+ },
2299
2317
  });
2300
2318
  React.useEffect(() => {
2301
2319
  if (!control._stateFlags.mount) {
@@ -2308,6 +2326,11 @@ function useForm(props = {}) {
2308
2326
  }
2309
2327
  control._removeUnmounted();
2310
2328
  });
2329
+ React.useEffect(() => {
2330
+ if (props.values && !deepEqual(props.values, control._defaultValues)) {
2331
+ control._reset(props.values, control._options.resetOptions);
2332
+ }
2333
+ }, [props.values, control]);
2311
2334
  React.useEffect(() => {
2312
2335
  formState.submitCount && control._focusError();
2313
2336
  }, [control, formState.submitCount]);