react-hook-form 7.43.1 → 7.44.0-next.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.
package/dist/index.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  export * from './controller';
2
+ export * from './form';
2
3
  export * from './logic';
3
4
  export * from './types';
4
5
  export * from './useController';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC;AAC7B,cAAc,SAAS,CAAC;AACxB,cAAc,SAAS,CAAC;AACxB,cAAc,iBAAiB,CAAC;AAChC,cAAc,iBAAiB,CAAC;AAChC,cAAc,WAAW,CAAC;AAC1B,cAAc,kBAAkB,CAAC;AACjC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,YAAY,CAAC;AAC3B,cAAc,SAAS,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC;AAC7B,cAAc,QAAQ,CAAC;AACvB,cAAc,SAAS,CAAC;AACxB,cAAc,SAAS,CAAC;AACxB,cAAc,iBAAiB,CAAC;AAChC,cAAc,iBAAiB,CAAC;AAChC,cAAc,WAAW,CAAC;AAC1B,cAAc,kBAAkB,CAAC;AACjC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,YAAY,CAAC;AAC3B,cAAc,SAAS,CAAC"}
@@ -1,4 +1,5 @@
1
- import React from 'react';
1
+ import * as React from 'react';
2
+ import React__default from 'react';
2
3
 
3
4
  var isCheckBoxInput = (element) => element.type === 'checkbox';
4
5
 
@@ -60,7 +61,7 @@ const INPUT_VALIDATION_RULES = {
60
61
  validate: 'validate',
61
62
  };
62
63
 
63
- const HookFormContext = React.createContext(null);
64
+ const HookFormContext = React__default.createContext(null);
64
65
  /**
65
66
  * This custom hook allows you to access the form context. useFormContext is intended to be used in deeply nested structures, where it would become inconvenient to pass the context as a prop. To be used with {@link FormProvider}.
66
67
  *
@@ -91,7 +92,7 @@ const HookFormContext = React.createContext(null);
91
92
  * }
92
93
  * ```
93
94
  */
94
- const useFormContext = () => React.useContext(HookFormContext);
95
+ const useFormContext = () => React__default.useContext(HookFormContext);
95
96
  /**
96
97
  * A provider component that propagates the `useForm` methods to all children components via [React Context](https://reactjs.org/docs/context.html) API. To be used with {@link useFormContext}.
97
98
  *
@@ -124,7 +125,7 @@ const useFormContext = () => React.useContext(HookFormContext);
124
125
  */
125
126
  const FormProvider = (props) => {
126
127
  const { children, ...data } = props;
127
- return (React.createElement(HookFormContext.Provider, { value: data }, children));
128
+ return (React__default.createElement(HookFormContext.Provider, { value: data }, children));
128
129
  };
129
130
 
130
131
  var getProxyFormState = (formState, control, localProxyFormState, isRoot = true) => {
@@ -169,9 +170,9 @@ var shouldSubscribeByName = (name, signalName, exact) => exact && signalName
169
170
  signalName.startsWith(currentName)));
170
171
 
171
172
  function useSubscribe(props) {
172
- const _props = React.useRef(props);
173
+ const _props = React__default.useRef(props);
173
174
  _props.current = props;
174
- React.useEffect(() => {
175
+ React__default.useEffect(() => {
175
176
  const subscription = !props.disabled &&
176
177
  _props.current.subject.subscribe({
177
178
  next: _props.current.next,
@@ -215,9 +216,9 @@ function useSubscribe(props) {
215
216
  function useFormState(props) {
216
217
  const methods = useFormContext();
217
218
  const { control = methods.control, disabled, name, exact } = props || {};
218
- const [formState, updateFormState] = React.useState(control._formState);
219
- const _mounted = React.useRef(true);
220
- const _localProxyFormState = React.useRef({
219
+ const [formState, updateFormState] = React__default.useState(control._formState);
220
+ const _mounted = React__default.useRef(true);
221
+ const _localProxyFormState = React__default.useRef({
221
222
  isDirty: false,
222
223
  isLoading: false,
223
224
  dirtyFields: false,
@@ -226,7 +227,7 @@ function useFormState(props) {
226
227
  isValid: false,
227
228
  errors: false,
228
229
  });
229
- const _name = React.useRef(name);
230
+ const _name = React__default.useRef(name);
230
231
  _name.current = name;
231
232
  useSubscribe({
232
233
  disabled,
@@ -239,7 +240,7 @@ function useFormState(props) {
239
240
  }),
240
241
  subject: control._subjects.state,
241
242
  });
242
- React.useEffect(() => {
243
+ React__default.useEffect(() => {
243
244
  _mounted.current = true;
244
245
  const isDirty = control._proxyFormState.isDirty && control._getDirty();
245
246
  if (isDirty !== control._formState.isDirty) {
@@ -324,7 +325,7 @@ function cloneObject(data) {
324
325
  function useWatch(props) {
325
326
  const methods = useFormContext();
326
327
  const { control = methods.control, name, defaultValue, disabled, exact, } = props || {};
327
- const _name = React.useRef(name);
328
+ const _name = React__default.useRef(name);
328
329
  _name.current = name;
329
330
  useSubscribe({
330
331
  disabled,
@@ -335,8 +336,8 @@ function useWatch(props) {
335
336
  }
336
337
  },
337
338
  });
338
- const [value, updateValue] = React.useState(control._getWatch(name, defaultValue));
339
- React.useEffect(() => control._removeUnmounted());
339
+ const [value, updateValue] = React__default.useState(control._getWatch(name, defaultValue));
340
+ React__default.useEffect(() => control._removeUnmounted());
340
341
  return value;
341
342
  }
342
343
 
@@ -378,11 +379,11 @@ function useController(props) {
378
379
  control,
379
380
  name,
380
381
  });
381
- const _registerProps = React.useRef(control.register(name, {
382
+ const _registerProps = React__default.useRef(control.register(name, {
382
383
  ...props.rules,
383
384
  value,
384
385
  }));
385
- React.useEffect(() => {
386
+ React__default.useEffect(() => {
386
387
  const updateMounted = (name, value) => {
387
388
  const field = get(control._fields, name);
388
389
  if (field) {
@@ -403,14 +404,14 @@ function useController(props) {
403
404
  field: {
404
405
  name,
405
406
  value,
406
- onChange: React.useCallback((event) => _registerProps.current.onChange({
407
+ onChange: React__default.useCallback((event) => _registerProps.current.onChange({
407
408
  target: {
408
409
  value: getEventValue(event),
409
410
  name: name,
410
411
  },
411
412
  type: EVENTS.CHANGE,
412
413
  }), [name]),
413
- onBlur: React.useCallback(() => _registerProps.current.onBlur({
414
+ onBlur: React__default.useCallback(() => _registerProps.current.onBlur({
414
415
  target: {
415
416
  value: get(control._formValues, name),
416
417
  name: name,
@@ -495,6 +496,103 @@ function useController(props) {
495
496
  */
496
497
  const Controller = (props) => props.render(useController(props));
497
498
 
499
+ const POST_REQUEST = 'post';
500
+ /**
501
+ * Form component to manage submission.
502
+ *
503
+ * @param props - to setup submission detail. {@link FormProps}
504
+ *
505
+ * @returns form component or headless render prop.
506
+ *
507
+ * @example
508
+ * ```tsx
509
+ * function App() {
510
+ * const { control, formState: { errors } } = useForm();
511
+ *
512
+ * return (
513
+ * <Form action="/api" control={control}>
514
+ * <input {...register("name")} />
515
+ * <p>{errors?.root?.server && 'Server error'}</p>
516
+ * <button>Submit</button>
517
+ * </form>
518
+ * );
519
+ * }
520
+ * ```
521
+ */
522
+ function Form(props) {
523
+ const methods = useFormContext();
524
+ const [mounted, setMounted] = React.useState(false);
525
+ const { control = methods.control, onSubmit, children, action, method = POST_REQUEST, headers, encType, onError, render, onSuccess, validateStatus, fetcher, ...rest } = props;
526
+ const isPostRequest = method === POST_REQUEST;
527
+ const submit = async (event) => {
528
+ let serverError = false;
529
+ await control.handleSubmit(async (values) => {
530
+ onSubmit && onSubmit(values);
531
+ if (action) {
532
+ const formData = new FormData();
533
+ let shouldStringifySubmissionData = false;
534
+ if (headers) {
535
+ shouldStringifySubmissionData =
536
+ headers['Content-Type'].includes('json');
537
+ }
538
+ else {
539
+ control._names.mount.forEach((name) => formData.append(name, get(values, name)));
540
+ }
541
+ if (!fetcher) {
542
+ try {
543
+ const response = await fetch(action, {
544
+ method,
545
+ headers: {
546
+ ...headers,
547
+ ...(encType ? { 'Content-Type': encType } : {}),
548
+ },
549
+ ...(isPostRequest
550
+ ? {
551
+ body: shouldStringifySubmissionData
552
+ ? JSON.stringify(values)
553
+ : formData,
554
+ }
555
+ : {}),
556
+ });
557
+ if (response &&
558
+ (validateStatus
559
+ ? !validateStatus(response.status)
560
+ : response.status < 200 || response.status >= 300)) {
561
+ serverError = true;
562
+ onError && onError({ response });
563
+ }
564
+ else {
565
+ onSuccess && onSuccess({ response });
566
+ }
567
+ }
568
+ catch (error) {
569
+ serverError = true;
570
+ onError && onError({ error });
571
+ }
572
+ }
573
+ else {
574
+ await fetcher(action, {
575
+ method,
576
+ values,
577
+ event,
578
+ });
579
+ }
580
+ }
581
+ })(event);
582
+ serverError &&
583
+ props.control &&
584
+ props.control._subjects.state.next({
585
+ isSubmitSuccessful: false,
586
+ });
587
+ };
588
+ React.useEffect(() => {
589
+ setMounted(true);
590
+ }, []);
591
+ return render ? (React.createElement(React.Fragment, null, render({
592
+ submit,
593
+ }))) : (React.createElement("form", { noValidate: mounted, action: action, method: method, encType: encType, onSubmit: submit, ...rest }, children));
594
+ }
595
+
498
596
  var appendErrors = (name, validateAllFieldCriteria, errors, type, message) => validateAllFieldCriteria
499
597
  ? {
500
598
  ...errors[name],
@@ -603,7 +701,7 @@ var isHTMLElement = (value) => {
603
701
  (owner && owner.defaultView ? owner.defaultView.HTMLElement : HTMLElement));
604
702
  };
605
703
 
606
- var isMessage = (value) => isString(value) || React.isValidElement(value);
704
+ var isMessage = (value) => isString(value);
607
705
 
608
706
  var isRadioInput = (element) => element.type === 'radio';
609
707
 
@@ -972,11 +1070,11 @@ var updateAt = (fieldValues, index, value) => {
972
1070
  function useFieldArray(props) {
973
1071
  const methods = useFormContext();
974
1072
  const { control = methods.control, name, keyName = 'id', shouldUnregister, } = props;
975
- const [fields, setFields] = React.useState(control._getFieldArray(name));
976
- const ids = React.useRef(control._getFieldArray(name).map(generateId));
977
- const _fieldIds = React.useRef(fields);
978
- const _name = React.useRef(name);
979
- const _actioned = React.useRef(false);
1073
+ const [fields, setFields] = React__default.useState(control._getFieldArray(name));
1074
+ const ids = React__default.useRef(control._getFieldArray(name).map(generateId));
1075
+ const _fieldIds = React__default.useRef(fields);
1076
+ const _name = React__default.useRef(name);
1077
+ const _actioned = React__default.useRef(false);
980
1078
  _name.current = name;
981
1079
  _fieldIds.current = fields;
982
1080
  control._names.array.add(name);
@@ -994,7 +1092,7 @@ function useFieldArray(props) {
994
1092
  },
995
1093
  subject: control._subjects.array,
996
1094
  });
997
- const updateValues = React.useCallback((updatedFieldArrayValues) => {
1095
+ const updateValues = React__default.useCallback((updatedFieldArrayValues) => {
998
1096
  _actioned.current = true;
999
1097
  control._updateFieldArray(name, updatedFieldArrayValues);
1000
1098
  }, [control, name]);
@@ -1081,7 +1179,7 @@ function useFieldArray(props) {
1081
1179
  setFields([...updatedFieldArrayValues]);
1082
1180
  control._updateFieldArray(name, [...updatedFieldArrayValues], (data) => data, {}, true, false);
1083
1181
  };
1084
- React.useEffect(() => {
1182
+ React__default.useEffect(() => {
1085
1183
  control._stateFlags.action = false;
1086
1184
  isWatched(name, control._names) && control._subjects.state.next({});
1087
1185
  if (_actioned.current &&
@@ -1120,7 +1218,7 @@ function useFieldArray(props) {
1120
1218
  control._names.focus = '';
1121
1219
  control._updateValid();
1122
1220
  }, [fields, name, control]);
1123
- React.useEffect(() => {
1221
+ React__default.useEffect(() => {
1124
1222
  !get(control._formValues, name) && control._updateFieldArray(name);
1125
1223
  return () => {
1126
1224
  (control._options.shouldUnregister || shouldUnregister) &&
@@ -1128,15 +1226,15 @@ function useFieldArray(props) {
1128
1226
  };
1129
1227
  }, [name, control, keyName, shouldUnregister]);
1130
1228
  return {
1131
- swap: React.useCallback(swap, [updateValues, name, control]),
1132
- move: React.useCallback(move, [updateValues, name, control]),
1133
- prepend: React.useCallback(prepend$1, [updateValues, name, control]),
1134
- append: React.useCallback(append$1, [updateValues, name, control]),
1135
- remove: React.useCallback(remove, [updateValues, name, control]),
1136
- insert: React.useCallback(insert$1, [updateValues, name, control]),
1137
- update: React.useCallback(update, [updateValues, name, control]),
1138
- replace: React.useCallback(replace, [updateValues, name, control]),
1139
- fields: React.useMemo(() => fields.map((field, index) => ({
1229
+ swap: React__default.useCallback(swap, [updateValues, name, control]),
1230
+ move: React__default.useCallback(move, [updateValues, name, control]),
1231
+ prepend: React__default.useCallback(prepend$1, [updateValues, name, control]),
1232
+ append: React__default.useCallback(append$1, [updateValues, name, control]),
1233
+ remove: React__default.useCallback(remove, [updateValues, name, control]),
1234
+ insert: React__default.useCallback(insert$1, [updateValues, name, control]),
1235
+ update: React__default.useCallback(update, [updateValues, name, control]),
1236
+ replace: React__default.useCallback(replace, [updateValues, name, control]),
1237
+ fields: React__default.useMemo(() => fields.map((field, index) => ({
1140
1238
  ...field,
1141
1239
  [keyName]: ids.current[index] || generateId(),
1142
1240
  })), [fields, keyName]),
@@ -1918,7 +2016,7 @@ function createFormControl(props = {}, flushRootRender) {
1918
2016
  : updateValidAndValue(name, true, options.value);
1919
2017
  return {
1920
2018
  ...(disabledIsDefined ? { disabled: options.disabled } : {}),
1921
- ...(_options.shouldUseNativeValidation
2019
+ ...(_options.shouldUseNativeValidation || _options.progressive
1922
2020
  ? {
1923
2021
  required: !!options.required,
1924
2022
  min: getRuleValue(options.min),
@@ -2161,6 +2259,8 @@ function createFormControl(props = {}, flushRootRender) {
2161
2259
  register,
2162
2260
  unregister,
2163
2261
  getFieldState,
2262
+ handleSubmit,
2263
+ setError,
2164
2264
  _executeSchema,
2165
2265
  _focusError,
2166
2266
  _getWatch,
@@ -2249,15 +2349,15 @@ function createFormControl(props = {}, flushRootRender) {
2249
2349
  * <input defaultValue="test" {...register("example")} />
2250
2350
  * <input {...register("exampleRequired", { required: true })} />
2251
2351
  * {errors.exampleRequired && <span>This field is required</span>}
2252
- * <input type="submit" />
2352
+ * <button>Submit</button>
2253
2353
  * </form>
2254
2354
  * );
2255
2355
  * }
2256
2356
  * ```
2257
2357
  */
2258
2358
  function useForm(props = {}) {
2259
- const _formControl = React.useRef();
2260
- const [formState, updateFormState] = React.useState({
2359
+ const _formControl = React__default.useRef();
2360
+ const [formState, updateFormState] = React__default.useState({
2261
2361
  isDirty: false,
2262
2362
  isValidating: false,
2263
2363
  isLoading: true,
@@ -2289,7 +2389,7 @@ function useForm(props = {}) {
2289
2389
  }
2290
2390
  },
2291
2391
  });
2292
- React.useEffect(() => {
2392
+ React__default.useEffect(() => {
2293
2393
  if (!control._stateFlags.mount) {
2294
2394
  control._updateValid();
2295
2395
  control._stateFlags.mount = true;
@@ -2300,17 +2400,17 @@ function useForm(props = {}) {
2300
2400
  }
2301
2401
  control._removeUnmounted();
2302
2402
  });
2303
- React.useEffect(() => {
2403
+ React__default.useEffect(() => {
2304
2404
  if (props.values && !deepEqual(props.values, control._defaultValues)) {
2305
2405
  control._reset(props.values, control._options.resetOptions);
2306
2406
  }
2307
2407
  }, [props.values, control]);
2308
- React.useEffect(() => {
2408
+ React__default.useEffect(() => {
2309
2409
  formState.submitCount && control._focusError();
2310
2410
  }, [control, formState.submitCount]);
2311
2411
  _formControl.current.formState = getProxyFormState(formState, control);
2312
2412
  return _formControl.current;
2313
2413
  }
2314
2414
 
2315
- export { Controller, FormProvider, appendErrors, get, set, useController, useFieldArray, useForm, useFormContext, useFormState, useWatch };
2415
+ export { Controller, Form, FormProvider, appendErrors, get, set, useController, useFieldArray, useForm, useFormContext, useFormState, useWatch };
2316
2416
  //# sourceMappingURL=index.esm.mjs.map