@octanejs/hook-form 0.1.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 (112) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +62 -0
  3. package/package.json +46 -0
  4. package/src/FormProvider.tsrx +76 -0
  5. package/src/FormProvider.tsrx.d.ts +10 -0
  6. package/src/constants.ts +31 -0
  7. package/src/controller.tsrx +8 -0
  8. package/src/controller.tsrx.d.ts +52 -0
  9. package/src/form.tsrx +119 -0
  10. package/src/form.tsrx.d.ts +6 -0
  11. package/src/formStateSubscribe.tsrx +10 -0
  12. package/src/formStateSubscribe.tsrx.d.ts +16 -0
  13. package/src/index.ts +19 -0
  14. package/src/logic/appendErrors.ts +19 -0
  15. package/src/logic/createFormControl.ts +1841 -0
  16. package/src/logic/generateId.ts +14 -0
  17. package/src/logic/generateWatchOutput.ts +27 -0
  18. package/src/logic/getCheckboxValue.ts +36 -0
  19. package/src/logic/getDirtyFields.ts +120 -0
  20. package/src/logic/getEventValue.ts +12 -0
  21. package/src/logic/getFieldValue.ts +33 -0
  22. package/src/logic/getFieldValueAs.ts +22 -0
  23. package/src/logic/getFocusFieldName.ts +13 -0
  24. package/src/logic/getNodeParentName.ts +4 -0
  25. package/src/logic/getProxyFormState.ts +33 -0
  26. package/src/logic/getRadioValue.ts +24 -0
  27. package/src/logic/getResolverOptions.ts +33 -0
  28. package/src/logic/getRuleValue.ts +16 -0
  29. package/src/logic/getValidateError.ts +22 -0
  30. package/src/logic/getValidationModes.ts +11 -0
  31. package/src/logic/getValueAndMessage.ts +12 -0
  32. package/src/logic/hasPromiseValidation.ts +27 -0
  33. package/src/logic/hasValidation.ts +12 -0
  34. package/src/logic/index.ts +3 -0
  35. package/src/logic/isNameInFieldArray.ts +7 -0
  36. package/src/logic/isWatched.ts +11 -0
  37. package/src/logic/iterateFieldsByAction.ts +37 -0
  38. package/src/logic/schemaErrorLookup.ts +54 -0
  39. package/src/logic/shouldRenderFormState.ts +25 -0
  40. package/src/logic/shouldSubscribeByName.ts +18 -0
  41. package/src/logic/skipValidation.ts +21 -0
  42. package/src/logic/unsetEmptyArray.ts +6 -0
  43. package/src/logic/updateFieldArrayRootError.ts +17 -0
  44. package/src/logic/validateField.ts +273 -0
  45. package/src/types/controller.ts +98 -0
  46. package/src/types/errors.ts +56 -0
  47. package/src/types/events.ts +26 -0
  48. package/src/types/fieldArray.ts +288 -0
  49. package/src/types/fields.ts +46 -0
  50. package/src/types/form.ts +961 -0
  51. package/src/types/index.ts +12 -0
  52. package/src/types/path/common.ts +391 -0
  53. package/src/types/path/eager.ts +224 -0
  54. package/src/types/path/index.ts +16 -0
  55. package/src/types/resolvers.ts +38 -0
  56. package/src/types/utils.ts +125 -0
  57. package/src/types/validator.ts +94 -0
  58. package/src/types/watch.ts +66 -0
  59. package/src/useController.ts +268 -0
  60. package/src/useFieldArray.ts +490 -0
  61. package/src/useForm.ts +182 -0
  62. package/src/useFormContext.ts +47 -0
  63. package/src/useFormControlContext.ts +25 -0
  64. package/src/useFormState.ts +86 -0
  65. package/src/useIsomorphicLayoutEffect.ts +6 -0
  66. package/src/useWatch.ts +356 -0
  67. package/src/utils/append.ts +4 -0
  68. package/src/utils/cloneObject.ts +32 -0
  69. package/src/utils/compact.ts +2 -0
  70. package/src/utils/convertToArrayPayload.ts +2 -0
  71. package/src/utils/createSubject.ts +48 -0
  72. package/src/utils/deepEqual.ts +81 -0
  73. package/src/utils/deepMerge.ts +27 -0
  74. package/src/utils/extractFormValues.ts +28 -0
  75. package/src/utils/fillEmptyArray.ts +3 -0
  76. package/src/utils/flatten.ts +23 -0
  77. package/src/utils/get.ts +29 -0
  78. package/src/utils/index.ts +3 -0
  79. package/src/utils/insert.ts +8 -0
  80. package/src/utils/isBoolean.ts +2 -0
  81. package/src/utils/isCheckBoxInput.ts +4 -0
  82. package/src/utils/isDateObject.ts +2 -0
  83. package/src/utils/isEmptyObject.ts +7 -0
  84. package/src/utils/isFileInput.ts +4 -0
  85. package/src/utils/isFunction.ts +2 -0
  86. package/src/utils/isHTMLElement.ts +13 -0
  87. package/src/utils/isKey.ts +4 -0
  88. package/src/utils/isMultipleSelect.ts +5 -0
  89. package/src/utils/isNullOrUndefined.ts +2 -0
  90. package/src/utils/isObject.ts +8 -0
  91. package/src/utils/isPlainObject.ts +8 -0
  92. package/src/utils/isPrimitive.ts +8 -0
  93. package/src/utils/isRadioInput.ts +4 -0
  94. package/src/utils/isRadioOrCheckbox.ts +8 -0
  95. package/src/utils/isRegex.ts +2 -0
  96. package/src/utils/isString.ts +2 -0
  97. package/src/utils/isUndefined.ts +2 -0
  98. package/src/utils/isWeb.ts +4 -0
  99. package/src/utils/live.ts +6 -0
  100. package/src/utils/move.ts +15 -0
  101. package/src/utils/noop.ts +2 -0
  102. package/src/utils/objectHasFunction.ts +11 -0
  103. package/src/utils/prepend.ts +7 -0
  104. package/src/utils/remove.ts +24 -0
  105. package/src/utils/set.ts +36 -0
  106. package/src/utils/sleep.ts +2 -0
  107. package/src/utils/stringToPath.ts +4 -0
  108. package/src/utils/swap.ts +4 -0
  109. package/src/utils/unset.ts +65 -0
  110. package/src/utils/update.ts +5 -0
  111. package/src/watch.tsrx +7 -0
  112. package/src/watch.tsrx.d.ts +42 -0
@@ -0,0 +1,961 @@
1
+ // Vendored from react-hook-form@7.81.0 src/types/form.ts.
2
+ // octane: structural stand-ins for the React types upstream references.
3
+ // Events are NATIVE DOM events in octane (no synthetic layer): a native Event
4
+ // structurally satisfies BaseSyntheticEvent below (persist is React-only and
5
+ // optional — upstream itself guards `event.persist && event.persist()`).
6
+ // Renderables (upstream's ReactNode) are `unknown`.
7
+ type BaseSyntheticEvent = {
8
+ type?: unknown;
9
+ target?: any;
10
+ preventDefault?: () => void;
11
+ persist?: () => void;
12
+ };
13
+ // Upstream: React.FormHTMLAttributes<HTMLFormElement>. Octane has no attribute
14
+ // prop types — native <form> attributes pass through untyped.
15
+ type FormHTMLAttributes = Record<string, unknown>;
16
+
17
+ import type { VALIDATION_MODE } from '../constants';
18
+ import type { Subject, Subscription } from '../utils/createSubject';
19
+
20
+ import type { ErrorOption, FieldError, FieldErrors } from './errors';
21
+ import type { EventType } from './events';
22
+ import type { FieldArray } from './fieldArray';
23
+ import type { FieldName, FieldRefs, FieldValue, FieldValues, InternalFieldName } from './fields';
24
+ import type { FieldArrayPath, FieldPath, FieldPathValue, FieldPathValues } from './path';
25
+ import type { Resolver } from './resolvers';
26
+ import type { DeepMap, DeepPartial, DeepPartialSkipArrayKey, Noop } from './utils';
27
+ import type { RegisterOptions, ValidateForm } from './validator';
28
+
29
+ declare const $NestedValue: unique symbol;
30
+
31
+ /**
32
+ * @deprecated to be removed in the next major version
33
+ */
34
+ export type NestedValue<TValue extends object = object> = {
35
+ [$NestedValue]: never;
36
+ } & TValue;
37
+
38
+ export type DefaultValues<TFieldValues> =
39
+ TFieldValues extends AsyncDefaultValues<TFieldValues>
40
+ ? DeepPartial<Awaited<TFieldValues>>
41
+ : DeepPartial<TFieldValues>;
42
+
43
+ export type InternalNameSet = Set<InternalFieldName>;
44
+
45
+ export type ValidationMode = typeof VALIDATION_MODE;
46
+
47
+ export type Mode = keyof ValidationMode;
48
+
49
+ export type ValidationModeFlags = {
50
+ isOnSubmit: boolean;
51
+ isOnBlur: boolean;
52
+ isOnChange: boolean;
53
+ isOnAll: boolean;
54
+ isOnTouch: boolean;
55
+ };
56
+
57
+ export type CriteriaMode = 'firstError' | 'all';
58
+
59
+ export type SubmitHandler<T> = (data: T, event?: BaseSyntheticEvent) => unknown | Promise<unknown>;
60
+
61
+ export type FormSubmitHandler<TTransformedValues> = (payload: {
62
+ data: TTransformedValues;
63
+ event?: BaseSyntheticEvent;
64
+ formData: FormData;
65
+ formDataJson: string;
66
+ method?: 'post' | 'put' | 'delete';
67
+ }) => unknown | Promise<unknown>;
68
+
69
+ export type SubmitErrorHandler<TFieldValues extends FieldValues> = (
70
+ errors: FieldErrors<TFieldValues>,
71
+ event?: BaseSyntheticEvent,
72
+ ) => unknown | Promise<unknown>;
73
+
74
+ export type SetValueConfig = Partial<{
75
+ shouldValidate: boolean;
76
+ shouldDirty: boolean;
77
+ shouldTouch: boolean;
78
+ }>;
79
+
80
+ export type TriggerConfig = Partial<{
81
+ shouldFocus: boolean;
82
+ }>;
83
+
84
+ export type ResetFieldConfig<
85
+ TFieldValues extends FieldValues,
86
+ TFieldName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,
87
+ > = Partial<{
88
+ keepDirty: boolean;
89
+ keepTouched: boolean;
90
+ keepError: boolean;
91
+ defaultValue: FieldPathValue<TFieldValues, TFieldName>;
92
+ }>;
93
+
94
+ export type ChangeHandler = (event: { target: any; type?: any }) => Promise<void | boolean>;
95
+
96
+ export type DelayCallback = (wait: number) => void;
97
+
98
+ type AsyncDefaultValues<TFieldValues> = (payload?: unknown) => Promise<TFieldValues>;
99
+
100
+ export type UseFormProps<
101
+ TFieldValues extends FieldValues = FieldValues,
102
+ TContext = any,
103
+ TTransformedValues = TFieldValues,
104
+ > = Partial<{
105
+ mode: Mode;
106
+ disabled: boolean;
107
+ reValidateMode: Exclude<Mode, 'onTouched' | 'all'>;
108
+ defaultValues: DefaultValues<TFieldValues> | AsyncDefaultValues<TFieldValues>;
109
+ values: TFieldValues;
110
+ errors: FieldErrors<TFieldValues>;
111
+ resetOptions: Parameters<UseFormReset<TFieldValues>>[1];
112
+ resolver: Resolver<TFieldValues, TContext, TTransformedValues>;
113
+ context: TContext;
114
+ shouldFocusError: boolean;
115
+ shouldUnregister: boolean;
116
+ shouldUseNativeValidation: boolean;
117
+ progressive: boolean;
118
+ criteriaMode: CriteriaMode;
119
+ delayError: number;
120
+ formControl?: Omit<UseFormReturn<TFieldValues, TContext, TTransformedValues>, 'formState'>;
121
+ validate: ValidateForm<TFieldValues>;
122
+ }>;
123
+
124
+ export type FieldNamesMarkedBoolean<TFieldValues extends FieldValues> = DeepMap<
125
+ DeepPartial<TFieldValues>,
126
+ boolean
127
+ >;
128
+
129
+ export type FormStateProxy<TFieldValues extends FieldValues = FieldValues> = {
130
+ isDirty: boolean;
131
+ isValidating: boolean;
132
+ dirtyFields: FieldNamesMarkedBoolean<TFieldValues>;
133
+ touchedFields: FieldNamesMarkedBoolean<TFieldValues>;
134
+ validatingFields: FieldNamesMarkedBoolean<TFieldValues>;
135
+ errors: boolean;
136
+ isValid: boolean;
137
+ };
138
+
139
+ export type ReadFormState = { [K in keyof FormStateProxy]: boolean | 'all' } & {
140
+ values?: boolean;
141
+ defaultValues?: boolean | 'all';
142
+ isSubmitted?: boolean | 'all';
143
+ submitCount?: boolean | 'all';
144
+ };
145
+
146
+ export type FormState<TFieldValues extends FieldValues> = {
147
+ isDirty: boolean;
148
+ isLoading: boolean;
149
+ isSubmitted: boolean;
150
+ isSubmitSuccessful: boolean;
151
+ isSubmitting: boolean;
152
+ isValidating: boolean;
153
+ isValid: boolean;
154
+ disabled: boolean;
155
+ submitCount: number;
156
+ defaultValues?: undefined | Readonly<DeepPartial<TFieldValues>>;
157
+ dirtyFields: Partial<Readonly<FieldNamesMarkedBoolean<TFieldValues>>>;
158
+ touchedFields: Partial<Readonly<FieldNamesMarkedBoolean<TFieldValues>>>;
159
+ validatingFields: Partial<Readonly<FieldNamesMarkedBoolean<TFieldValues>>>;
160
+ errors: FieldErrors<TFieldValues>;
161
+ isReady: boolean;
162
+ };
163
+
164
+ export type KeepStateOptions = Partial<{
165
+ keepDirtyValues: boolean;
166
+ keepErrors: boolean;
167
+ keepDirty: boolean;
168
+ keepValues: boolean;
169
+ keepDefaultValues: boolean;
170
+ keepIsSubmitted: boolean;
171
+ keepIsSubmitSuccessful: boolean;
172
+ keepTouched: boolean;
173
+ keepIsValidating: boolean;
174
+ keepIsValid: boolean;
175
+ keepSubmitCount: boolean;
176
+ keepFieldsRef: boolean;
177
+ }>;
178
+
179
+ export type SetFieldValue<TFieldValues extends FieldValues> = FieldValue<TFieldValues>;
180
+
181
+ export type RefCallBack = (instance: any) => void;
182
+
183
+ export type UseFormRegisterReturn<TFieldName extends InternalFieldName = InternalFieldName> = {
184
+ // octane: upstream's `onChange` — native events make `input` the
185
+ // per-keystroke event, so the handler is exposed under `onInput`.
186
+ onInput: ChangeHandler;
187
+ onBlur: ChangeHandler;
188
+ ref: RefCallBack;
189
+ name: TFieldName;
190
+ min?: string | number;
191
+ max?: string | number;
192
+ maxLength?: number;
193
+ minLength?: number;
194
+ pattern?: string;
195
+ required?: boolean;
196
+ disabled?: boolean;
197
+ };
198
+
199
+ /**
200
+ * Register field into hook form with or without the actual DOM ref. You can invoke register anywhere in the component including at `useEffect`.
201
+ *
202
+ * @remarks
203
+ * [API](https://react-hook-form.com/docs/useform/register) • [Demo](https://codesandbox.io/s/react-hook-form-register-ts-ip2j3) • [Video](https://www.youtube.com/watch?v=JFIpCoajYkA)
204
+ *
205
+ * @param name - the path name to the form field value, name is required and unique
206
+ * @param options - register options include validation, disabled, unregister, value as and dependent validation
207
+ *
208
+ * @returns onInput, onBlur, name, ref, and native HTML validation attributes if browser validation is enabled.
209
+ *
210
+ * @example
211
+ * ```tsx
212
+ * // Register HTML native input
213
+ * <input {...register("input")} />
214
+ * <select {...register("select")} />
215
+ *
216
+ * // Register options
217
+ * <textarea {...register("textarea", { required: "This is required.", maxLength: 20 })} />
218
+ * <input type="number" {...register("name2", { valueAsNumber: true })} />
219
+ * <input {...register("name3", { deps: ["name2"] })} />
220
+ *
221
+ * // Register custom field at useEffect
222
+ * useEffect(() => {
223
+ * register("name4");
224
+ * register("name5", { value: "hiddenValue" });
225
+ * }, [register])
226
+ *
227
+ * // Register without ref
228
+ * const { onChange, onBlur, name } = register("name6")
229
+ * <input onChange={onChange} onBlur={onBlur} name={name} />
230
+ * ```
231
+ */
232
+ export type UseFormRegister<TFieldValues extends FieldValues> = <
233
+ TFieldName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,
234
+ >(
235
+ name: TFieldName,
236
+ options?: RegisterOptions<TFieldValues, TFieldName>,
237
+ ) => UseFormRegisterReturn<TFieldName>;
238
+
239
+ export type SetFocusOptions = Partial<{
240
+ shouldSelect: boolean;
241
+ }>;
242
+
243
+ /**
244
+ * Set focus on a registered field. You can start to invoke this method after all fields are mounted to the DOM.
245
+ *
246
+ * @remarks
247
+ * [API](https://react-hook-form.com/docs/useform/setfocus) • [Demo](https://codesandbox.io/s/setfocus-rolus)
248
+ *
249
+ * @param name - the path name to the form field value.
250
+ * @param options - input focus behavior options
251
+ *
252
+ * @example
253
+ * ```tsx
254
+ * useEffect(() => {
255
+ * setFocus("name");
256
+ * }, [setFocus])
257
+ * // shouldSelect allows to select input's content on focus
258
+ * <button onClick={() => setFocus("name", { shouldSelect: true })}>Focus</button>
259
+ * ```
260
+ */
261
+ export type UseFormSetFocus<TFieldValues extends FieldValues> = <
262
+ TFieldName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,
263
+ >(
264
+ name: TFieldName,
265
+ options?: SetFocusOptions,
266
+ ) => void;
267
+
268
+ type EitherOption<T> = {
269
+ [K in keyof T]: {
270
+ [P in K]: T[P];
271
+ } & Partial<Record<Exclude<keyof T, K>, never>>;
272
+ }[keyof T];
273
+
274
+ export type GetValuesConfig = EitherOption<{
275
+ dirtyFields: boolean;
276
+ touchedFields: boolean;
277
+ }>;
278
+
279
+ export type UseFormGetValues<TFieldValues extends FieldValues> = {
280
+ /**
281
+ * Get the entire form values when no argument is supplied to this function.
282
+ *
283
+ * @remarks
284
+ * [API](https://react-hook-form.com/docs/useform/getvalues) • [Demo](https://codesandbox.io/s/react-hook-form-v7-ts-getvalues-txsfg)
285
+ *
286
+ * @returns form values
287
+ *
288
+ * @example
289
+ * ```tsx
290
+ * <button onClick={() => getValues()}>getValues</button>
291
+ *
292
+ * <input {...register("name", {
293
+ * validate: (value, formValues) => formValues.otherField === value;
294
+ * })} />
295
+ * ```
296
+ */
297
+ (name?: undefined, config?: GetValuesConfig): TFieldValues;
298
+ /**
299
+ * Get a single field value.
300
+ *
301
+ * @remarks
302
+ * [API](https://react-hook-form.com/docs/useform/getvalues) • [Demo](https://codesandbox.io/s/react-hook-form-v7-ts-getvalues-txsfg)
303
+ *
304
+ * @param name - the path name to the form field value.
305
+ * @param config - return touched or dirty fields
306
+ *
307
+ * @returns the single field value
308
+ *
309
+ * @example
310
+ * ```tsx
311
+ * <button onClick={() => getValues("name")}>getValues</button>
312
+ *
313
+ * <input {...register("name", {
314
+ * validate: () => getValues('otherField') === "test";
315
+ * })} />
316
+ * ```
317
+ */
318
+ <TFieldName extends FieldPath<TFieldValues>>(
319
+ name: TFieldName,
320
+ config?: GetValuesConfig,
321
+ ): FieldPathValue<TFieldValues, TFieldName>;
322
+ /**
323
+ * Get an array of field values.
324
+ *
325
+ * @remarks
326
+ * [API](https://react-hook-form.com/docs/useform/getvalues) • [Demo](https://codesandbox.io/s/react-hook-form-v7-ts-getvalues-txsfg)
327
+ *
328
+ * @param names - an array of field names
329
+ * @param config - return touched or dirty fields
330
+ *
331
+ * @returns An array of field values
332
+ *
333
+ * @example
334
+ * ```tsx
335
+ * <button onClick={() => getValues(["name", "name1"])}>getValues</button>
336
+ *
337
+ * <input {...register("name", {
338
+ * validate: () => getValues(["fieldA", "fieldB"]).includes("test");
339
+ * })} />
340
+ * ```
341
+ */
342
+ <TFieldNames extends FieldPath<TFieldValues>[]>(
343
+ names: readonly [...TFieldNames],
344
+ config?: GetValuesConfig,
345
+ ): [...FieldPathValues<TFieldValues, TFieldNames>];
346
+ };
347
+
348
+ /**
349
+ * This method will return individual field states. It will be useful when you are trying to retrieve the nested value field state in a typesafe approach.
350
+ *
351
+ * @remarks
352
+ * [API](https://react-hook-form.com/docs/useform/getfieldstate) • [Demo](https://codesandbox.io/s/getfieldstate-jvekk)
353
+ *
354
+ * @param name - the path name to the form field value.
355
+ *
356
+ * @returns invalid, isDirty, isTouched, isValidating, and error object
357
+ *
358
+ * @example
359
+ * ```tsx
360
+ * // those formState has to be subscribed
361
+ * const { formState: { dirtyFields, errors, touchedFields } } = formState();
362
+ * getFieldState('name')
363
+ * // Get field state when form state is not subscribed yet
364
+ * getFieldState('name', formState)
365
+ *
366
+ * // It's ok to combine with useFormState
367
+ * const formState = useFormState();
368
+ * getFieldState('name')
369
+ * getFieldState('name', formState)
370
+ * ```
371
+ */
372
+ export type UseFormGetFieldState<TFieldValues extends FieldValues> = <
373
+ TFieldName extends FieldPath<TFieldValues>,
374
+ >(
375
+ name: TFieldName,
376
+ formState?: FormState<TFieldValues>,
377
+ ) => {
378
+ invalid: boolean;
379
+ isDirty: boolean;
380
+ isTouched: boolean;
381
+ isValidating: boolean;
382
+ error?: FieldError;
383
+ };
384
+
385
+ /**
386
+ * This method will allow you to subscribe to formState without component render
387
+ *
388
+ * @remarks
389
+ * [API](https://react-hook-form.com/docs/useform/subscribe) • [Demo](https://codesandbox.io/s/subscribe)
390
+ *
391
+ * @param options - subscription options on which formState subscribe to
392
+ *
393
+ * @example
394
+ * ```tsx
395
+ const { subscribe } = useForm()
396
+
397
+ useEffect(() => {
398
+ subscribe({
399
+ formState: { isDirty: true },
400
+ callback: () => {}
401
+ })
402
+ })
403
+ * ```
404
+ */
405
+ export type UseFormSubscribe<TFieldValues extends FieldValues> = <
406
+ TFieldNames extends readonly FieldPath<TFieldValues>[],
407
+ >(payload: {
408
+ name?: readonly [...TFieldNames] | TFieldNames[number];
409
+ formState?: Partial<ReadFormState>;
410
+ callback: (
411
+ data: Partial<FormState<TFieldValues>> & {
412
+ values: TFieldValues;
413
+ name?: InternalFieldName;
414
+ type?: EventType;
415
+ },
416
+ ) => void;
417
+ exact?: boolean;
418
+ }) => () => void;
419
+
420
+ export type UseFormWatch<TFieldValues extends FieldValues> = {
421
+ /**
422
+ * Watch and subscribe to the entire form update/change based on onChange and re-render at the useForm.
423
+ *
424
+ * @remarks
425
+ * [API](https://react-hook-form.com/docs/useform/watch) • [Demo](https://codesandbox.io/s/react-hook-form-watch-v7-ts-8et1d) • [Video](https://www.youtube.com/watch?v=3qLd69WMqKk)
426
+ *
427
+ * @returns the entire form values
428
+ *
429
+ * @example
430
+ * ```tsx
431
+ * const formValues = watch();
432
+ * ```
433
+ */
434
+ (): TFieldValues;
435
+ /**
436
+ * Watch and subscribe to an array of fields used outside of render.
437
+ *
438
+ * @remarks
439
+ * [API](https://react-hook-form.com/docs/useform/watch) • [Demo](https://codesandbox.io/s/react-hook-form-watch-v7-ts-8et1d) • [Video](https://www.youtube.com/watch?v=3qLd69WMqKk)
440
+ *
441
+ * @param names - an array of field names
442
+ * @param defaultValue - defaultValues for the entire form
443
+ *
444
+ * @returns an array of field values
445
+ *
446
+ * @example
447
+ * ```tsx
448
+ * const [name, name1] = watch(["name", "name1"]);
449
+ * ```
450
+ */
451
+ <TFieldNames extends readonly FieldPath<TFieldValues>[]>(
452
+ names: readonly [...TFieldNames],
453
+ defaultValue?: DeepPartial<TFieldValues>,
454
+ ): FieldPathValues<TFieldValues, TFieldNames>;
455
+ /**
456
+ * Watch and subscribe to a single field used outside of render.
457
+ *
458
+ * @remarks
459
+ * [API](https://react-hook-form.com/docs/useform/watch) • [Demo](https://codesandbox.io/s/react-hook-form-watch-v7-ts-8et1d) • [Video](https://www.youtube.com/watch?v=3qLd69WMqKk)
460
+ *
461
+ * @param name - the path name to the form field value.
462
+ * @param defaultValue - defaultValues for the entire form
463
+ *
464
+ * @returns the single field value
465
+ *
466
+ * @example
467
+ * ```tsx
468
+ * const name = watch("name");
469
+ * ```
470
+ */
471
+ <TFieldName extends FieldPath<TFieldValues>>(
472
+ name: TFieldName,
473
+ defaultValue?: FieldPathValue<TFieldValues, TFieldName>,
474
+ ): FieldPathValue<TFieldValues, TFieldName>;
475
+ /**
476
+ * Subscribe to field update/change without trigger re-render
477
+ *
478
+ * @remarks
479
+ * [API](https://react-hook-form.com/docs/useform/watch) • [Demo](https://codesandbox.io/s/react-hook-form-watch-v7-ts-8et1d) • [Video](https://www.youtube.com/watch?v=3qLd69WMqKk)
480
+ *
481
+ * @param callback - call back function to subscribe all fields change and return unsubscribe function
482
+ * @param defaultValues - defaultValues for the entire form
483
+ *
484
+ * @returns unsubscribe function
485
+ *
486
+ * @example
487
+ * ```tsx
488
+ * useEffect(() => {
489
+ * const { unsubscribe } = watch((value) => {
490
+ * console.log(value);
491
+ * });
492
+ * return () => unsubscribe();
493
+ * }, [watch])
494
+ * ```
495
+ */
496
+ (callback: WatchObserver<TFieldValues>, defaultValues?: DeepPartial<TFieldValues>): Subscription;
497
+ };
498
+
499
+ /**
500
+ * Trigger field or form validation
501
+ *
502
+ * @remarks
503
+ * [API](https://react-hook-form.com/docs/useform/trigger) • [Demo](https://codesandbox.io/s/react-hook-form-v7-ts-triggervalidation-forked-xs7hl) • [Video](https://www.youtube.com/watch?v=-bcyJCDjksE)
504
+ *
505
+ * @param name - provide empty argument will trigger the entire form validation, an array of field names will validate an array of fields, and a single field name will only trigger that field's validation.
506
+ * @param options - should focus on the error field
507
+ *
508
+ * @returns validation result
509
+ *
510
+ * @example
511
+ * ```tsx
512
+ * useEffect(() => {
513
+ * trigger();
514
+ * }, [trigger])
515
+ *
516
+ * <button onClick={async () => {
517
+ * const result = await trigger(); // result will be a boolean value
518
+ * }}>
519
+ * trigger
520
+ * </button>
521
+ * ```
522
+ */
523
+ export type UseFormTrigger<TFieldValues extends FieldValues> = (
524
+ name?: FieldPath<TFieldValues> | FieldPath<TFieldValues>[] | readonly FieldPath<TFieldValues>[],
525
+ options?: TriggerConfig,
526
+ ) => Promise<boolean>;
527
+
528
+ /**
529
+ * Clear the entire form errors.
530
+ *
531
+ * @remarks
532
+ * [API](https://react-hook-form.com/docs/useform/clearerrors) • [Demo](https://codesandbox.io/s/react-hook-form-v7-ts-clearerrors-w3ymx)
533
+ *
534
+ * @param name - the path name to the form field value.
535
+ *
536
+ * @example
537
+ * Clear all errors
538
+ * ```tsx
539
+ * clearErrors(); // clear the entire form error
540
+ * clearErrors(["name", "name1"]) // clear an array of fields' error
541
+ * clearErrors("name2"); // clear a single field error
542
+ * ```
543
+ */
544
+ export type UseFormClearErrors<TFieldValues extends FieldValues> = (
545
+ name?:
546
+ | FieldPath<TFieldValues>
547
+ | FieldPath<TFieldValues>[]
548
+ | readonly FieldPath<TFieldValues>[]
549
+ | `root.${string}`
550
+ | 'root'
551
+ | 'form'
552
+ | `form.${string}`,
553
+ ) => void;
554
+
555
+ /**
556
+ * Set a single field value, or a group of fields value.
557
+ *
558
+ * @remarks
559
+ * [API](https://react-hook-form.com/docs/useform/setvalue) • [Demo](https://codesandbox.io/s/react-hook-form-v7-ts-setvalue-8z9hx) • [Video](https://www.youtube.com/watch?v=qpv51sCH3fI)
560
+ *
561
+ * @param name - the path name to the form field value.
562
+ * @param value - field value
563
+ * @param options - should validate or update form state
564
+ *
565
+ * @example
566
+ * ```tsx
567
+ * // Update a single field
568
+ * setValue('name', 'value', {
569
+ * shouldValidate: true, // trigger validation
570
+ * shouldTouch: true, // update touched fields form state
571
+ * shouldDirty: true, // update dirty and dirty fields form state
572
+ * });
573
+ *
574
+ * // Update a group fields
575
+ * setValue('root', {
576
+ * a: 'test', // setValue('root.a', 'data')
577
+ * b: 'test1', // setValue('root.b', 'data')
578
+ * });
579
+ *
580
+ * // Update a nested object field
581
+ * setValue('select', { label: 'test', value: 'Test' });
582
+ * ```
583
+ */
584
+ export type UseFormSetValue<TFieldValues extends FieldValues> = <
585
+ TFieldName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,
586
+ >(
587
+ name: TFieldName,
588
+ value: FieldPathValue<TFieldValues, TFieldName>,
589
+ options?: SetValueConfig,
590
+ ) => void;
591
+
592
+ export type UseFormSetValues<TFieldValues extends FieldValues> = (
593
+ value: Partial<TFieldValues> | ResetAction<TFieldValues>,
594
+ options?: SetValueConfig,
595
+ ) => void;
596
+
597
+ /**
598
+ * Set an error for the field. When set an error which is not associated to a field then manual `clearErrors` invoke is required.
599
+ *
600
+ * @remarks
601
+ * [API](https://react-hook-form.com/docs/useform/seterror) • [Demo](https://codesandbox.io/s/react-hook-form-v7-ts-seterror-nfxxu) • [Video](https://www.youtube.com/watch?v=raMqvE0YyIY)
602
+ *
603
+ * @param name - the path name to the form field value.
604
+ * @param error - an error object which contains type and optional message
605
+ * @param options - whether or not to focus on the field
606
+ *
607
+ * @example
608
+ * ```tsx
609
+ * // when the error is not associated with any fields, `clearError` will need to invoke to clear the error
610
+ * const onSubmit = () => setError("serverError", { type: "server", message: "Error occurred"})
611
+ *
612
+ * <button onClick={() => setError("name", { type: "min" })} />
613
+ *
614
+ * // focus on the input after setting the error
615
+ * <button onClick={() => setError("name", { type: "max" }, { shouldFocus: true })} />
616
+ * ```
617
+ */
618
+ export type UseFormSetError<TFieldValues extends FieldValues> = (
619
+ name: FieldPath<TFieldValues> | `root.${string}` | 'root' | 'form' | `form.${string}`,
620
+ error: ErrorOption,
621
+ options?: {
622
+ shouldFocus: boolean;
623
+ },
624
+ ) => void;
625
+
626
+ /**
627
+ * Unregister a field reference and remove its value.
628
+ *
629
+ * @remarks
630
+ * [API](https://react-hook-form.com/docs/useform/unregister) • [Demo](https://codesandbox.io/s/react-hook-form-unregister-4k2ey) • [Video](https://www.youtube.com/watch?v=TM99g_NW5Gk&feature=emb_imp_woyt)
631
+ *
632
+ * @param name - the path name to the form field value.
633
+ * @param options - keep form state options
634
+ *
635
+ * @example
636
+ * ```tsx
637
+ * register("name", { required: true })
638
+ *
639
+ * <button onClick={() => unregister("name")} />
640
+ * // there are various keep options to retain formState
641
+ * <button onClick={() => unregister("name", { keepErrors: true })} />
642
+ * ```
643
+ */
644
+ export type UseFormUnregister<TFieldValues extends FieldValues> = (
645
+ name?: FieldPath<TFieldValues> | FieldPath<TFieldValues>[] | readonly FieldPath<TFieldValues>[],
646
+ options?: Omit<
647
+ KeepStateOptions,
648
+ 'keepIsSubmitted' | 'keepSubmitCount' | 'keepValues' | 'keepDefaultValues' | 'keepErrors'
649
+ > & { keepValue?: boolean; keepDefaultValue?: boolean; keepError?: boolean },
650
+ ) => void;
651
+
652
+ /**
653
+ * Validate the entire form. Handle submit and error callback.
654
+ *
655
+ * @remarks
656
+ * [API](https://react-hook-form.com/docs/useform/handlesubmit) • [Demo](https://codesandbox.io/s/react-hook-form-handlesubmit-ts-v7-lcrtu) • [Video](https://www.youtube.com/watch?v=KzcPKB9SOEk)
657
+ *
658
+ * @param onValid - callback function invoked after form pass validation
659
+ * @param onInvalid - callback function invoked when form failed validation
660
+ *
661
+ * @returns callback - return callback function
662
+ *
663
+ * @example
664
+ * ```tsx
665
+ * const onSubmit = (data) => console.log(data);
666
+ * const onError = (error) => console.log(error);
667
+ *
668
+ * <form onSubmit={handleSubmit(onSubmit, onError)} />
669
+ * ```
670
+ */
671
+ export type UseFormHandleSubmit<
672
+ TFieldValues extends FieldValues,
673
+ TTransformedValues = TFieldValues,
674
+ > = (
675
+ onValid: SubmitHandler<TTransformedValues>,
676
+ onInvalid?: SubmitErrorHandler<TFieldValues>,
677
+ ) => (e?: BaseSyntheticEvent) => Promise<void>;
678
+
679
+ /**
680
+ * Reset a field state and reference.
681
+ *
682
+ * @remarks
683
+ * [API](https://react-hook-form.com/docs/useform/resetfield) • [Demo](https://codesandbox.io/s/priceless-firefly-d0kuv) • [Video](https://www.youtube.com/watch?v=IdLFcNaEFEo)
684
+ *
685
+ * @param name - the path name to the form field value.
686
+ * @param options - keep form state options
687
+ *
688
+ * @example
689
+ * ```tsx
690
+ * <input {...register("firstName", { required: true })} />
691
+ * <button type="button" onClick={() => resetField("firstName"))}>Reset</button>
692
+ * ```
693
+ */
694
+ export type UseFormResetField<TFieldValues extends FieldValues> = <
695
+ TFieldName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,
696
+ >(
697
+ name: TFieldName,
698
+ options?: ResetFieldConfig<TFieldValues, TFieldName>,
699
+ ) => void;
700
+
701
+ type ResetAction<TFieldValues> = (formValues: TFieldValues) => TFieldValues;
702
+
703
+ /**
704
+ * Reset at the entire form state.
705
+ *
706
+ * @remarks
707
+ * [API](https://react-hook-form.com/docs/useform/reset) • [Demo](https://codesandbox.io/s/react-hook-form-reset-v7-ts-pu901) • [Video](https://www.youtube.com/watch?v=qmCLBjyPwVk)
708
+ *
709
+ * @param values - the entire form values to be reset
710
+ * @param keepStateOptions - keep form state options
711
+ *
712
+ * @example
713
+ * ```tsx
714
+ * useEffect(() => {
715
+ * // reset the entire form after component mount or form defaultValues is ready
716
+ * reset({
717
+ * fieldA: "test"
718
+ * fieldB: "test"
719
+ * });
720
+ * }, [reset])
721
+ *
722
+ * // reset by combine with existing form values
723
+ * reset({
724
+ * ...getValues(),
725
+ * fieldB: "test"
726
+ *});
727
+ *
728
+ * // reset and keep form state
729
+ * reset({
730
+ * ...getValues(),
731
+ *}, {
732
+ * keepErrors: true,
733
+ * keepDirty: true
734
+ *});
735
+ * ```
736
+ */
737
+ export type UseFormReset<TFieldValues extends FieldValues> = (
738
+ values?: DefaultValues<TFieldValues> | TFieldValues | ResetAction<TFieldValues>,
739
+ keepStateOptions?: KeepStateOptions,
740
+ ) => void;
741
+
742
+ /**
743
+ * Reset the default values of the form and recompute `dirtyFields`/`isDirty` without changing user values.
744
+ *
745
+ * @remarks
746
+ * [API](https://react-hook-form.com/docs/useform/resetdefaultvalues)
747
+ *
748
+ * @param values - the new default values
749
+ * @param options - options to keep dirty or isValid state
750
+ *
751
+ * @example
752
+ * ```tsx
753
+ * // After a successful submission, update defaults to the submitted values
754
+ * // so that dirtyFields/isDirty reflect changes made after that point.
755
+ * const onSuccess = () => {
756
+ * resetDefaultValues(submittedValues);
757
+ * };
758
+ * ```
759
+ */
760
+ export type UseFormResetDefaultValues<TFieldValues extends FieldValues> = (
761
+ values: DefaultValues<TFieldValues> | TFieldValues,
762
+ options?: Partial<Pick<KeepStateOptions, 'keepDirty' | 'keepIsValid'>>,
763
+ ) => void;
764
+
765
+ export type WatchInternal<TFieldValues> = (
766
+ fieldNames?: InternalFieldName | InternalFieldName[],
767
+ defaultValue?: DeepPartial<TFieldValues>,
768
+ isMounted?: boolean,
769
+ isGlobal?: boolean,
770
+ ) =>
771
+ | FieldPathValue<FieldValues, InternalFieldName>
772
+ | FieldPathValues<FieldValues, InternalFieldName[]>;
773
+
774
+ export type GetIsDirty = <TName extends InternalFieldName, TData>(
775
+ name?: TName,
776
+ data?: TData,
777
+ ) => boolean;
778
+
779
+ export type FormStateSubjectRef<TFieldValues extends FieldValues> = Subject<
780
+ Partial<FormState<TFieldValues>> & {
781
+ name?: InternalFieldName;
782
+ values?: TFieldValues;
783
+ type?: EventType;
784
+ }
785
+ >;
786
+
787
+ export type Subjects<TFieldValues extends FieldValues = FieldValues> = {
788
+ array: Subject<{
789
+ name?: InternalFieldName;
790
+ values?: FieldValues;
791
+ }>;
792
+ state: FormStateSubjectRef<TFieldValues>;
793
+ };
794
+
795
+ export type Names = {
796
+ mount: InternalNameSet;
797
+ unMount: InternalNameSet;
798
+ disabled: InternalNameSet;
799
+ array: InternalNameSet;
800
+ watch: InternalNameSet;
801
+ registerName: InternalNameSet;
802
+ focus?: InternalFieldName;
803
+ watchAll?: boolean;
804
+ };
805
+
806
+ export type BatchFieldArrayUpdate = <
807
+ T extends Function,
808
+ TFieldValues extends FieldValues,
809
+ TFieldArrayName extends FieldArrayPath<TFieldValues> = FieldArrayPath<TFieldValues>,
810
+ >(
811
+ name: InternalFieldName,
812
+ updatedFieldArrayValues?: Partial<FieldArray<TFieldValues, TFieldArrayName>>[],
813
+ method?: T,
814
+ args?: Partial<{
815
+ argA: unknown;
816
+ argB: unknown;
817
+ }>,
818
+ shouldSetValue?: boolean,
819
+ shouldUpdateFieldsAndErrors?: boolean,
820
+ ) => void;
821
+
822
+ export type FromSubscribe<TFieldValues extends FieldValues> = <
823
+ TFieldNames extends readonly FieldPath<TFieldValues>[],
824
+ >(payload: {
825
+ name?: readonly [...TFieldNames] | TFieldNames[number];
826
+ formState?: Partial<ReadFormState>;
827
+ callback: (
828
+ data: Partial<FormState<TFieldValues>> & {
829
+ values: TFieldValues;
830
+ name?: InternalFieldName;
831
+ },
832
+ ) => void;
833
+ exact?: boolean;
834
+ reRenderRoot?: boolean;
835
+ }) => () => void;
836
+
837
+ export type Control<
838
+ TFieldValues extends FieldValues = FieldValues,
839
+ TContext = any,
840
+ TTransformedValues = TFieldValues,
841
+ > = {
842
+ _subjects: Subjects<TFieldValues>;
843
+ _removeUnmounted: Noop;
844
+ _names: Names;
845
+ _state: {
846
+ mount: boolean;
847
+ action: boolean;
848
+ watch: boolean;
849
+ };
850
+ _reset: UseFormReset<TFieldValues>;
851
+ _options: UseFormProps<TFieldValues, TContext, TTransformedValues>;
852
+ _getDirty: GetIsDirty;
853
+ _resetDefaultValues: Noop;
854
+ _formState: FormState<TFieldValues>;
855
+ _setValid: (shouldUpdateValid?: boolean) => void;
856
+ _fields: FieldRefs;
857
+ _formValues: FieldValues;
858
+ _proxyFormState: ReadFormState;
859
+ _defaultValues: Partial<DefaultValues<TFieldValues>>;
860
+ _getWatch: WatchInternal<TFieldValues>;
861
+ _setFieldArray: BatchFieldArrayUpdate;
862
+ _getFieldArray: <TFieldArrayValues>(name: InternalFieldName) => Partial<TFieldArrayValues>[];
863
+ _setErrors: (errors: FieldErrors<TFieldValues>) => void;
864
+ _setDisabledField: (props: { disabled?: boolean; name: FieldName<any> }) => void;
865
+ _runSchema: (names: InternalFieldName[]) => Promise<{ errors: FieldErrors }>;
866
+ _updateIsValidating: (names?: InternalFieldName[], isValidating?: boolean) => void;
867
+ _focusError: () => boolean | undefined;
868
+ _disableForm: (disabled?: boolean) => void;
869
+ _subscribe: FromSubscribe<TFieldValues>;
870
+ register: UseFormRegister<TFieldValues>;
871
+ handleSubmit: UseFormHandleSubmit<TFieldValues, TTransformedValues>;
872
+ unregister: UseFormUnregister<TFieldValues>;
873
+ getFieldState: UseFormGetFieldState<TFieldValues>;
874
+ setError: UseFormSetError<TFieldValues>;
875
+ };
876
+
877
+ export type WatchObserver<TFieldValues extends FieldValues> = (
878
+ value: DeepPartialSkipArrayKey<TFieldValues>,
879
+ info: {
880
+ name?: FieldPath<TFieldValues>;
881
+ type?: EventType;
882
+ values?: unknown;
883
+ },
884
+ ) => void;
885
+
886
+ export type UseFormReturn<
887
+ TFieldValues extends FieldValues = FieldValues,
888
+ TContext = any,
889
+ TTransformedValues = TFieldValues,
890
+ > = {
891
+ watch: UseFormWatch<TFieldValues>;
892
+ getValues: UseFormGetValues<TFieldValues>;
893
+ getFieldState: UseFormGetFieldState<TFieldValues>;
894
+ setError: UseFormSetError<TFieldValues>;
895
+ clearErrors: UseFormClearErrors<TFieldValues>;
896
+ setValue: UseFormSetValue<TFieldValues>;
897
+ setValues: UseFormSetValues<TFieldValues>;
898
+ trigger: UseFormTrigger<TFieldValues>;
899
+ formState: FormState<TFieldValues>;
900
+ resetField: UseFormResetField<TFieldValues>;
901
+ reset: UseFormReset<TFieldValues>;
902
+ resetDefaultValues: UseFormResetDefaultValues<TFieldValues>;
903
+ handleSubmit: UseFormHandleSubmit<TFieldValues, TTransformedValues>;
904
+ unregister: UseFormUnregister<TFieldValues>;
905
+ control: Control<TFieldValues, TContext, TTransformedValues>;
906
+ register: UseFormRegister<TFieldValues>;
907
+ setFocus: UseFormSetFocus<TFieldValues>;
908
+ subscribe: UseFormSubscribe<TFieldValues>;
909
+ };
910
+
911
+ export type UseFormStateProps<
912
+ TFieldValues extends FieldValues,
913
+ TTransformedValues = TFieldValues,
914
+ > = Partial<{
915
+ control?: Control<TFieldValues, any, TTransformedValues>;
916
+ disabled?: boolean;
917
+ name?: FieldPath<TFieldValues> | FieldPath<TFieldValues>[] | readonly FieldPath<TFieldValues>[];
918
+ exact?: boolean;
919
+ }>;
920
+
921
+ export type UseFormStateReturn<TFieldValues extends FieldValues> = FormState<TFieldValues>;
922
+
923
+ export type FormProviderProps<
924
+ TFieldValues extends FieldValues = FieldValues,
925
+ TContext = any,
926
+ TTransformedValues = TFieldValues,
927
+ > = {
928
+ children: unknown;
929
+ } & UseFormReturn<TFieldValues, TContext, TTransformedValues>;
930
+
931
+ export type FormProps<TFieldValues extends FieldValues, TTransformedValues = TFieldValues> = Omit<
932
+ FormHTMLAttributes,
933
+ 'onError' | 'onSubmit'
934
+ > &
935
+ Partial<{
936
+ control: Control<TFieldValues, any, TTransformedValues>;
937
+ headers: Record<string, string>;
938
+ validateStatus: (status: number) => boolean;
939
+ onError: ({
940
+ response,
941
+ error,
942
+ }:
943
+ | {
944
+ response: Response;
945
+ error?: undefined;
946
+ }
947
+ | {
948
+ response?: undefined;
949
+ error: unknown;
950
+ }) => void;
951
+ onSuccess: ({ response }: { response: Response }) => void;
952
+ onSubmit: FormSubmitHandler<TTransformedValues>;
953
+ method: 'post' | 'put' | 'delete';
954
+ children: unknown;
955
+ render: (props: { submit: (e?: Event) => void }) => unknown;
956
+ encType:
957
+ | 'application/x-www-form-urlencoded'
958
+ | 'multipart/form-data'
959
+ | 'text/plain'
960
+ | 'application/json';
961
+ }>;