mobx-react-hook-form 2.1.3 → 3.0.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.
- package/README.md +1 -4
- package/mobx-form/mobx-form.d.ts +234 -19
- package/mobx-form/mobx-form.d.ts.map +1 -1
- package/mobx-form/mobx-form.js +307 -56
- package/mobx-form/mobx-form.types.d.ts +2 -3
- package/mobx-form/mobx-form.types.d.ts.map +1 -1
- package/package.json +2 -6
- package/mobx-form/mobx-form-state.d.ts +0 -28
- package/mobx-form/mobx-form-state.d.ts.map +0 -1
- package/mobx-form/mobx-form-state.js +0 -76
package/README.md
CHANGED
|
@@ -39,11 +39,8 @@ class YourVM {
|
|
|
39
39
|
|
|
40
40
|
|
|
41
41
|
const YourView = () => {
|
|
42
|
-
const form = useMobxForm(yourVM.form)
|
|
43
|
-
|
|
44
|
-
|
|
45
42
|
return (
|
|
46
|
-
<form onSubmit={form.
|
|
43
|
+
<form onSubmit={yourVM.form.submit} onReset={yourVM.form.reset}>
|
|
47
44
|
<Controller control={form.control} name={'username'} render={...} />
|
|
48
45
|
</form>
|
|
49
46
|
)
|
package/mobx-form/mobx-form.d.ts
CHANGED
|
@@ -1,33 +1,248 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { BaseSyntheticEvent } from 'react';
|
|
2
|
+
import { Control, createFormControl, DeepMap, DeepPartial, FieldErrors, FieldValues, FormState, UseFormClearErrors, UseFormRegister, UseFormReset, UseFormResetField, UseFormSetError, UseFormSetFocus, UseFormTrigger, UseFormUnregister } from 'react-hook-form';
|
|
3
3
|
import { MobxFormParams } from './mobx-form.types.js';
|
|
4
|
-
|
|
4
|
+
type FormFullState<TFieldValues extends FieldValues> = FormState<TFieldValues> & {
|
|
5
|
+
values: TFieldValues;
|
|
6
|
+
};
|
|
7
|
+
export declare class MobxForm<TFieldValues extends FieldValues = FieldValues, TContext = any, TTransformedValues = TFieldValues> implements FormFullState<TFieldValues> {
|
|
5
8
|
private config;
|
|
6
|
-
|
|
9
|
+
values: TFieldValues;
|
|
10
|
+
isDirty: boolean;
|
|
11
|
+
isLoading: boolean;
|
|
12
|
+
isSubmitted: boolean;
|
|
13
|
+
isSubmitSuccessful: boolean;
|
|
14
|
+
isSubmitting: boolean;
|
|
15
|
+
isValidating: boolean;
|
|
16
|
+
isValid: boolean;
|
|
17
|
+
disabled: boolean;
|
|
18
|
+
submitCount: number;
|
|
19
|
+
defaultValues: Readonly<DeepPartial<TFieldValues>> | undefined;
|
|
20
|
+
dirtyFields: Partial<Readonly<DeepMap<DeepPartial<TFieldValues>, boolean>>>;
|
|
21
|
+
touchedFields: Partial<Readonly<DeepMap<DeepPartial<TFieldValues>, boolean>>>;
|
|
22
|
+
validatingFields: Partial<Readonly<DeepMap<DeepPartial<TFieldValues>, boolean>>>;
|
|
23
|
+
errors: FieldErrors<TFieldValues>;
|
|
24
|
+
isReady: boolean;
|
|
7
25
|
/**
|
|
8
|
-
*
|
|
9
|
-
*
|
|
26
|
+
* Set an error for the field. When set an error which is not associated to a field then manual `clearErrors` invoke is required.
|
|
27
|
+
*
|
|
28
|
+
* @remarks
|
|
29
|
+
* [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)
|
|
30
|
+
*
|
|
31
|
+
* @param name - the path name to the form field value.
|
|
32
|
+
* @param error - an error object which contains type and optional message
|
|
33
|
+
* @param options - whether or not to focus on the field
|
|
34
|
+
*
|
|
35
|
+
* @example
|
|
36
|
+
* ```tsx
|
|
37
|
+
* // when the error is not associated with any fields, `clearError` will need to invoke to clear the error
|
|
38
|
+
* const onSubmit = () => setError("serverError", { type: "server", message: "Error occurred"})
|
|
39
|
+
*
|
|
40
|
+
* <button onClick={() => setError("name", { type: "min" })} />
|
|
41
|
+
*
|
|
42
|
+
* // focus on the input after setting the error
|
|
43
|
+
* <button onClick={() => setError("name", { type: "max" }, { shouldFocus: true })} />
|
|
44
|
+
* ```
|
|
10
45
|
*/
|
|
11
|
-
|
|
12
|
-
protected handleSubmit(...args: Parameters<SubmitHandler<TTransformedValues>>): void | Promise<void>;
|
|
13
|
-
protected handleSubmitFailed(...args: Parameters<SubmitErrorHandler<TFieldValues>>): void | Promise<void>;
|
|
14
|
-
protected handleReset(): void;
|
|
46
|
+
setError: UseFormSetError<TFieldValues>;
|
|
15
47
|
/**
|
|
16
|
-
*
|
|
48
|
+
* Clear the entire form errors.
|
|
49
|
+
*
|
|
50
|
+
* @remarks
|
|
51
|
+
* [API](https://react-hook-form.com/docs/useform/clearerrors) • [Demo](https://codesandbox.io/s/react-hook-form-v7-ts-clearerrors-w3ymx)
|
|
52
|
+
*
|
|
53
|
+
* @param name - the path name to the form field value.
|
|
54
|
+
*
|
|
55
|
+
* @example
|
|
56
|
+
* Clear all errors
|
|
57
|
+
* ```tsx
|
|
58
|
+
* clearErrors(); // clear the entire form error
|
|
59
|
+
* clearErrors(["name", "name1"]) // clear an array of fields' error
|
|
60
|
+
* clearErrors("name2"); // clear a single field error
|
|
61
|
+
* ```
|
|
62
|
+
*/
|
|
63
|
+
clearErrors: UseFormClearErrors<TFieldValues>;
|
|
64
|
+
/**
|
|
65
|
+
* Trigger field or form validation
|
|
66
|
+
*
|
|
67
|
+
* @remarks
|
|
68
|
+
* [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)
|
|
69
|
+
*
|
|
70
|
+
* @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.
|
|
71
|
+
* @param options - should focus on the error field
|
|
72
|
+
*
|
|
73
|
+
* @returns validation result
|
|
74
|
+
*
|
|
75
|
+
* @example
|
|
76
|
+
* ```tsx
|
|
77
|
+
* useEffect(() => {
|
|
78
|
+
* trigger();
|
|
79
|
+
* }, [trigger])
|
|
80
|
+
*
|
|
81
|
+
* <button onClick={async () => {
|
|
82
|
+
* const result = await trigger(); // result will be a boolean value
|
|
83
|
+
* }}>
|
|
84
|
+
* trigger
|
|
85
|
+
* </button>
|
|
86
|
+
* ```
|
|
87
|
+
*/
|
|
88
|
+
trigger: UseFormTrigger<TFieldValues>;
|
|
89
|
+
/**
|
|
90
|
+
* Reset a field state and reference.
|
|
91
|
+
*
|
|
92
|
+
* @remarks
|
|
93
|
+
* [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)
|
|
94
|
+
*
|
|
95
|
+
* @param name - the path name to the form field value.
|
|
96
|
+
* @param options - keep form state options
|
|
97
|
+
*
|
|
98
|
+
* @example
|
|
99
|
+
* ```tsx
|
|
100
|
+
* <input {...register("firstName", { required: true })} />
|
|
101
|
+
* <button type="button" onClick={() => resetField("firstName"))}>Reset</button>
|
|
102
|
+
* ```
|
|
103
|
+
*/
|
|
104
|
+
resetField: UseFormResetField<TFieldValues>;
|
|
105
|
+
/**
|
|
106
|
+
* Unregister a field reference and remove its value.
|
|
107
|
+
*
|
|
108
|
+
* @remarks
|
|
109
|
+
* [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)
|
|
110
|
+
*
|
|
111
|
+
* @param name - the path name to the form field value.
|
|
112
|
+
* @param options - keep form state options
|
|
113
|
+
*
|
|
114
|
+
* @example
|
|
115
|
+
* ```tsx
|
|
116
|
+
* register("name", { required: true })
|
|
117
|
+
*
|
|
118
|
+
* <button onClick={() => unregister("name")} />
|
|
119
|
+
* // there are various keep options to retain formState
|
|
120
|
+
* <button onClick={() => unregister("name", { keepErrors: true })} />
|
|
121
|
+
* ```
|
|
122
|
+
*/
|
|
123
|
+
unregister: UseFormUnregister<TFieldValues>;
|
|
124
|
+
/**
|
|
125
|
+
* Form control
|
|
126
|
+
*
|
|
127
|
+
* @remarks
|
|
128
|
+
* [API](https://react-hook-form.com/docs/useform/control)
|
|
129
|
+
*
|
|
17
130
|
*/
|
|
18
|
-
|
|
131
|
+
control: Control<TFieldValues, TContext, TTransformedValues>;
|
|
19
132
|
/**
|
|
20
|
-
* form
|
|
133
|
+
* Register field into hook form with or without the actual DOM ref. You can invoke register anywhere in the component including at `useEffect`.
|
|
134
|
+
*
|
|
135
|
+
* @remarks
|
|
136
|
+
* [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)
|
|
137
|
+
*
|
|
138
|
+
* @param name - the path name to the form field value, name is required and unique
|
|
139
|
+
* @param options - register options include validation, disabled, unregister, value as and dependent validation
|
|
140
|
+
*
|
|
141
|
+
* @returns onChange, onBlur, name, ref, and native contribute attribute if browser validation is enabled.
|
|
142
|
+
*
|
|
143
|
+
* @example
|
|
144
|
+
* ```tsx
|
|
145
|
+
* // Register HTML native input
|
|
146
|
+
* <input {...register("input")} />
|
|
147
|
+
* <select {...register("select")} />
|
|
148
|
+
*
|
|
149
|
+
* // Register options
|
|
150
|
+
* <textarea {...register("textarea", { required: "This is required.", maxLength: 20 })} />
|
|
151
|
+
* <input type="number" {...register("name2", { valueAsNumber: true })} />
|
|
152
|
+
* <input {...register("name3", { deps: ["name2"] })} />
|
|
153
|
+
*
|
|
154
|
+
* // Register custom field at useEffect
|
|
155
|
+
* useEffect(() => {
|
|
156
|
+
* register("name4");
|
|
157
|
+
* register("name5", { value: "hiddenValue" });
|
|
158
|
+
* }, [register])
|
|
159
|
+
*
|
|
160
|
+
* // Register without ref
|
|
161
|
+
* const { onChange, onBlur, name } = register("name6")
|
|
162
|
+
* <input onChange={onChange} onBlur={onBlur} name={name} />
|
|
163
|
+
* ```
|
|
21
164
|
*/
|
|
22
|
-
|
|
23
|
-
get state(): MobxFormStateReadonly<TFieldValues>;
|
|
165
|
+
register: UseFormRegister<TFieldValues>;
|
|
24
166
|
/**
|
|
25
|
-
*
|
|
167
|
+
* Set focus on a registered field. You can start to invoke this method after all fields are mounted to the DOM.
|
|
168
|
+
*
|
|
169
|
+
* @remarks
|
|
170
|
+
* [API](https://react-hook-form.com/docs/useform/setfocus) • [Demo](https://codesandbox.io/s/setfocus-rolus)
|
|
171
|
+
*
|
|
172
|
+
* @param name - the path name to the form field value.
|
|
173
|
+
* @param options - input focus behavior options
|
|
174
|
+
*
|
|
175
|
+
* @example
|
|
176
|
+
* ```tsx
|
|
177
|
+
* useEffect(() => {
|
|
178
|
+
* setFocus("name");
|
|
179
|
+
* }, [setFocus])
|
|
180
|
+
* // shouldSelect allows to select input's content on focus
|
|
181
|
+
* <button onClick={() => setFocus("name", { shouldSelect: true })}>Focus</button>
|
|
182
|
+
* ```
|
|
26
183
|
*/
|
|
27
|
-
|
|
184
|
+
setFocus: UseFormSetFocus<TFieldValues>;
|
|
185
|
+
/**
|
|
186
|
+
* Reset at the entire form state.
|
|
187
|
+
*
|
|
188
|
+
* @remarks
|
|
189
|
+
* [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)
|
|
190
|
+
*
|
|
191
|
+
* @param values - the entire form values to be reset
|
|
192
|
+
* @param keepStateOptions - keep form state options
|
|
193
|
+
*
|
|
194
|
+
* @example
|
|
195
|
+
* ```tsx
|
|
196
|
+
* useEffect(() => {
|
|
197
|
+
* // reset the entire form after component mount or form defaultValues is ready
|
|
198
|
+
* reset({
|
|
199
|
+
* fieldA: "test"
|
|
200
|
+
* fieldB: "test"
|
|
201
|
+
* });
|
|
202
|
+
* }, [reset])
|
|
203
|
+
*
|
|
204
|
+
* // reset by combine with existing form values
|
|
205
|
+
* reset({
|
|
206
|
+
* ...getValues(),
|
|
207
|
+
* fieldB: "test"
|
|
208
|
+
*});
|
|
209
|
+
*
|
|
210
|
+
* // reset and keep form state
|
|
211
|
+
* reset({
|
|
212
|
+
* ...getValues(),
|
|
213
|
+
*}, {
|
|
214
|
+
* keepErrors: true,
|
|
215
|
+
* keepDirty: true
|
|
216
|
+
*});
|
|
217
|
+
* ```
|
|
218
|
+
*/
|
|
219
|
+
resetForm: UseFormReset<TFieldValues>;
|
|
220
|
+
protected abortController: AbortController;
|
|
221
|
+
/**
|
|
222
|
+
* Original react-hook-form form
|
|
223
|
+
*/
|
|
224
|
+
originalForm: ReturnType<typeof createFormControl<TFieldValues, TContext, TTransformedValues>>;
|
|
28
225
|
constructor(config: MobxFormParams<TFieldValues, TContext, TTransformedValues>);
|
|
29
226
|
destroy(): void;
|
|
30
|
-
|
|
31
|
-
|
|
227
|
+
/**
|
|
228
|
+
* Method to manually submit form.
|
|
229
|
+
* Used to attach this method to <form /> element
|
|
230
|
+
*
|
|
231
|
+
* @example
|
|
232
|
+
*
|
|
233
|
+
* <form onSubmit={form.submit} />
|
|
234
|
+
*/
|
|
235
|
+
submit(e?: BaseSyntheticEvent): Promise<TTransformedValues>;
|
|
236
|
+
/**
|
|
237
|
+
* Method to manually reset all form.
|
|
238
|
+
* Used to attach this method to <form /> element
|
|
239
|
+
*
|
|
240
|
+
* @example
|
|
241
|
+
*
|
|
242
|
+
* <form onReset={form.reset} />
|
|
243
|
+
*/
|
|
244
|
+
reset(e?: BaseSyntheticEvent): void;
|
|
245
|
+
private updateFormState;
|
|
32
246
|
}
|
|
247
|
+
export {};
|
|
33
248
|
//# sourceMappingURL=mobx-form.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mobx-form.d.ts","sourceRoot":"","sources":["../../src/mobx-form/mobx-form.ts"],"names":[],"mappings":"AAGA,OAAO,EACL,iBAAiB,EACjB,WAAW,EACX,kBAAkB,EAClB,
|
|
1
|
+
{"version":3,"file":"mobx-form.d.ts","sourceRoot":"","sources":["../../src/mobx-form/mobx-form.ts"],"names":[],"mappings":"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"}
|
package/mobx-form/mobx-form.js
CHANGED
|
@@ -1,60 +1,243 @@
|
|
|
1
1
|
/* eslint-disable @typescript-eslint/ban-ts-comment */
|
|
2
2
|
import { LinkedAbortController } from 'linked-abort-controller';
|
|
3
|
-
import { action,
|
|
3
|
+
import { action, makeObservable, observable } from 'mobx';
|
|
4
4
|
import { createFormControl, } from 'react-hook-form';
|
|
5
|
-
import { MobxFormState } from './mobx-form-state.js';
|
|
6
5
|
export class MobxForm {
|
|
7
6
|
config;
|
|
8
|
-
|
|
7
|
+
values;
|
|
8
|
+
isDirty = false;
|
|
9
|
+
isLoading = false;
|
|
10
|
+
isSubmitted = false;
|
|
11
|
+
isSubmitSuccessful = false;
|
|
12
|
+
isSubmitting = false;
|
|
13
|
+
isValidating = false;
|
|
14
|
+
isValid = false;
|
|
15
|
+
disabled = false;
|
|
16
|
+
submitCount = 0;
|
|
17
|
+
defaultValues;
|
|
18
|
+
dirtyFields = {};
|
|
19
|
+
touchedFields = {};
|
|
20
|
+
validatingFields = {};
|
|
21
|
+
errors = {};
|
|
22
|
+
isReady = false;
|
|
9
23
|
/**
|
|
10
|
-
*
|
|
11
|
-
*
|
|
24
|
+
* Set an error for the field. When set an error which is not associated to a field then manual `clearErrors` invoke is required.
|
|
25
|
+
*
|
|
26
|
+
* @remarks
|
|
27
|
+
* [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)
|
|
28
|
+
*
|
|
29
|
+
* @param name - the path name to the form field value.
|
|
30
|
+
* @param error - an error object which contains type and optional message
|
|
31
|
+
* @param options - whether or not to focus on the field
|
|
32
|
+
*
|
|
33
|
+
* @example
|
|
34
|
+
* ```tsx
|
|
35
|
+
* // when the error is not associated with any fields, `clearError` will need to invoke to clear the error
|
|
36
|
+
* const onSubmit = () => setError("serverError", { type: "server", message: "Error occurred"})
|
|
37
|
+
*
|
|
38
|
+
* <button onClick={() => setError("name", { type: "min" })} />
|
|
39
|
+
*
|
|
40
|
+
* // focus on the input after setting the error
|
|
41
|
+
* <button onClick={() => setError("name", { type: "max" }, { shouldFocus: true })} />
|
|
42
|
+
* ```
|
|
12
43
|
*/
|
|
13
|
-
|
|
14
|
-
handleSubmit(
|
|
15
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
16
|
-
...args) {
|
|
17
|
-
this.config.onSubmit?.(...args);
|
|
18
|
-
// used to override
|
|
19
|
-
}
|
|
20
|
-
handleSubmitFailed(
|
|
21
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
22
|
-
...args) {
|
|
23
|
-
this.config.onSubmitFailed?.(...args);
|
|
24
|
-
// used to override
|
|
25
|
-
}
|
|
26
|
-
handleReset() {
|
|
27
|
-
this.config.onReset?.();
|
|
28
|
-
// used to override
|
|
29
|
-
}
|
|
44
|
+
setError;
|
|
30
45
|
/**
|
|
31
|
-
*
|
|
46
|
+
* Clear the entire form errors.
|
|
47
|
+
*
|
|
48
|
+
* @remarks
|
|
49
|
+
* [API](https://react-hook-form.com/docs/useform/clearerrors) • [Demo](https://codesandbox.io/s/react-hook-form-v7-ts-clearerrors-w3ymx)
|
|
50
|
+
*
|
|
51
|
+
* @param name - the path name to the form field value.
|
|
52
|
+
*
|
|
53
|
+
* @example
|
|
54
|
+
* Clear all errors
|
|
55
|
+
* ```tsx
|
|
56
|
+
* clearErrors(); // clear the entire form error
|
|
57
|
+
* clearErrors(["name", "name1"]) // clear an array of fields' error
|
|
58
|
+
* clearErrors("name2"); // clear a single field error
|
|
59
|
+
* ```
|
|
32
60
|
*/
|
|
33
|
-
|
|
61
|
+
clearErrors;
|
|
34
62
|
/**
|
|
35
|
-
*
|
|
63
|
+
* Trigger field or form validation
|
|
64
|
+
*
|
|
65
|
+
* @remarks
|
|
66
|
+
* [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)
|
|
67
|
+
*
|
|
68
|
+
* @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.
|
|
69
|
+
* @param options - should focus on the error field
|
|
70
|
+
*
|
|
71
|
+
* @returns validation result
|
|
72
|
+
*
|
|
73
|
+
* @example
|
|
74
|
+
* ```tsx
|
|
75
|
+
* useEffect(() => {
|
|
76
|
+
* trigger();
|
|
77
|
+
* }, [trigger])
|
|
78
|
+
*
|
|
79
|
+
* <button onClick={async () => {
|
|
80
|
+
* const result = await trigger(); // result will be a boolean value
|
|
81
|
+
* }}>
|
|
82
|
+
* trigger
|
|
83
|
+
* </button>
|
|
84
|
+
* ```
|
|
36
85
|
*/
|
|
37
|
-
|
|
38
|
-
get state() {
|
|
39
|
-
return this._state;
|
|
40
|
-
}
|
|
86
|
+
trigger;
|
|
41
87
|
/**
|
|
42
|
-
*
|
|
88
|
+
* Reset a field state and reference.
|
|
89
|
+
*
|
|
90
|
+
* @remarks
|
|
91
|
+
* [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)
|
|
92
|
+
*
|
|
93
|
+
* @param name - the path name to the form field value.
|
|
94
|
+
* @param options - keep form state options
|
|
95
|
+
*
|
|
96
|
+
* @example
|
|
97
|
+
* ```tsx
|
|
98
|
+
* <input {...register("firstName", { required: true })} />
|
|
99
|
+
* <button type="button" onClick={() => resetField("firstName"))}>Reset</button>
|
|
100
|
+
* ```
|
|
43
101
|
*/
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
102
|
+
resetField;
|
|
103
|
+
/**
|
|
104
|
+
* Unregister a field reference and remove its value.
|
|
105
|
+
*
|
|
106
|
+
* @remarks
|
|
107
|
+
* [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)
|
|
108
|
+
*
|
|
109
|
+
* @param name - the path name to the form field value.
|
|
110
|
+
* @param options - keep form state options
|
|
111
|
+
*
|
|
112
|
+
* @example
|
|
113
|
+
* ```tsx
|
|
114
|
+
* register("name", { required: true })
|
|
115
|
+
*
|
|
116
|
+
* <button onClick={() => unregister("name")} />
|
|
117
|
+
* // there are various keep options to retain formState
|
|
118
|
+
* <button onClick={() => unregister("name", { keepErrors: true })} />
|
|
119
|
+
* ```
|
|
120
|
+
*/
|
|
121
|
+
unregister;
|
|
122
|
+
/**
|
|
123
|
+
* Form control
|
|
124
|
+
*
|
|
125
|
+
* @remarks
|
|
126
|
+
* [API](https://react-hook-form.com/docs/useform/control)
|
|
127
|
+
*
|
|
128
|
+
*/
|
|
129
|
+
control;
|
|
130
|
+
/**
|
|
131
|
+
* Register field into hook form with or without the actual DOM ref. You can invoke register anywhere in the component including at `useEffect`.
|
|
132
|
+
*
|
|
133
|
+
* @remarks
|
|
134
|
+
* [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)
|
|
135
|
+
*
|
|
136
|
+
* @param name - the path name to the form field value, name is required and unique
|
|
137
|
+
* @param options - register options include validation, disabled, unregister, value as and dependent validation
|
|
138
|
+
*
|
|
139
|
+
* @returns onChange, onBlur, name, ref, and native contribute attribute if browser validation is enabled.
|
|
140
|
+
*
|
|
141
|
+
* @example
|
|
142
|
+
* ```tsx
|
|
143
|
+
* // Register HTML native input
|
|
144
|
+
* <input {...register("input")} />
|
|
145
|
+
* <select {...register("select")} />
|
|
146
|
+
*
|
|
147
|
+
* // Register options
|
|
148
|
+
* <textarea {...register("textarea", { required: "This is required.", maxLength: 20 })} />
|
|
149
|
+
* <input type="number" {...register("name2", { valueAsNumber: true })} />
|
|
150
|
+
* <input {...register("name3", { deps: ["name2"] })} />
|
|
151
|
+
*
|
|
152
|
+
* // Register custom field at useEffect
|
|
153
|
+
* useEffect(() => {
|
|
154
|
+
* register("name4");
|
|
155
|
+
* register("name5", { value: "hiddenValue" });
|
|
156
|
+
* }, [register])
|
|
157
|
+
*
|
|
158
|
+
* // Register without ref
|
|
159
|
+
* const { onChange, onBlur, name } = register("name6")
|
|
160
|
+
* <input onChange={onChange} onBlur={onBlur} name={name} />
|
|
161
|
+
* ```
|
|
162
|
+
*/
|
|
163
|
+
register;
|
|
164
|
+
/**
|
|
165
|
+
* Set focus on a registered field. You can start to invoke this method after all fields are mounted to the DOM.
|
|
166
|
+
*
|
|
167
|
+
* @remarks
|
|
168
|
+
* [API](https://react-hook-form.com/docs/useform/setfocus) • [Demo](https://codesandbox.io/s/setfocus-rolus)
|
|
169
|
+
*
|
|
170
|
+
* @param name - the path name to the form field value.
|
|
171
|
+
* @param options - input focus behavior options
|
|
172
|
+
*
|
|
173
|
+
* @example
|
|
174
|
+
* ```tsx
|
|
175
|
+
* useEffect(() => {
|
|
176
|
+
* setFocus("name");
|
|
177
|
+
* }, [setFocus])
|
|
178
|
+
* // shouldSelect allows to select input's content on focus
|
|
179
|
+
* <button onClick={() => setFocus("name", { shouldSelect: true })}>Focus</button>
|
|
180
|
+
* ```
|
|
181
|
+
*/
|
|
182
|
+
setFocus;
|
|
183
|
+
/**
|
|
184
|
+
* Reset at the entire form state.
|
|
185
|
+
*
|
|
186
|
+
* @remarks
|
|
187
|
+
* [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)
|
|
188
|
+
*
|
|
189
|
+
* @param values - the entire form values to be reset
|
|
190
|
+
* @param keepStateOptions - keep form state options
|
|
191
|
+
*
|
|
192
|
+
* @example
|
|
193
|
+
* ```tsx
|
|
194
|
+
* useEffect(() => {
|
|
195
|
+
* // reset the entire form after component mount or form defaultValues is ready
|
|
196
|
+
* reset({
|
|
197
|
+
* fieldA: "test"
|
|
198
|
+
* fieldB: "test"
|
|
199
|
+
* });
|
|
200
|
+
* }, [reset])
|
|
201
|
+
*
|
|
202
|
+
* // reset by combine with existing form values
|
|
203
|
+
* reset({
|
|
204
|
+
* ...getValues(),
|
|
205
|
+
* fieldB: "test"
|
|
206
|
+
*});
|
|
207
|
+
*
|
|
208
|
+
* // reset and keep form state
|
|
209
|
+
* reset({
|
|
210
|
+
* ...getValues(),
|
|
211
|
+
*}, {
|
|
212
|
+
* keepErrors: true,
|
|
213
|
+
* keepDirty: true
|
|
214
|
+
*});
|
|
215
|
+
* ```
|
|
216
|
+
*/
|
|
217
|
+
resetForm;
|
|
218
|
+
abortController;
|
|
219
|
+
/**
|
|
220
|
+
* Original react-hook-form form
|
|
221
|
+
*/
|
|
222
|
+
originalForm;
|
|
47
223
|
constructor(config) {
|
|
48
224
|
this.config = config;
|
|
49
|
-
this.params = config;
|
|
50
225
|
this.abortController = new LinkedAbortController(config.abortSignal);
|
|
51
|
-
this.
|
|
52
|
-
this.
|
|
53
|
-
|
|
226
|
+
this.originalForm = createFormControl(config);
|
|
227
|
+
this.setError = this.originalForm.setError;
|
|
228
|
+
this.clearErrors = this.originalForm.clearErrors;
|
|
229
|
+
this.trigger = this.originalForm.trigger;
|
|
230
|
+
this.resetField = this.originalForm.resetField;
|
|
231
|
+
this.unregister = this.originalForm.unregister;
|
|
232
|
+
this.control = this.originalForm.control;
|
|
233
|
+
this.register = this.originalForm.register;
|
|
234
|
+
this.setFocus = this.originalForm.setFocus;
|
|
235
|
+
this.resetForm = this.originalForm.reset;
|
|
236
|
+
Object.assign(this, {
|
|
237
|
+
values: this.originalForm.getValues(),
|
|
54
238
|
defaultValues: config.defaultValues || {},
|
|
55
239
|
});
|
|
56
|
-
|
|
57
|
-
const subscription = this.form.subscribe({
|
|
240
|
+
const subscription = this.originalForm.subscribe({
|
|
58
241
|
formState: {
|
|
59
242
|
values: true,
|
|
60
243
|
errors: true,
|
|
@@ -66,34 +249,102 @@ export class MobxForm {
|
|
|
66
249
|
validatingFields: true,
|
|
67
250
|
},
|
|
68
251
|
callback: (rawFormState) => {
|
|
69
|
-
this.
|
|
252
|
+
this.updateFormState(rawFormState);
|
|
70
253
|
},
|
|
71
254
|
});
|
|
255
|
+
observable.deep(this, 'values');
|
|
256
|
+
observable.ref(this, 'isDirty');
|
|
257
|
+
observable.ref(this, 'isLoading');
|
|
258
|
+
observable.ref(this, 'isSubmitted');
|
|
259
|
+
observable.ref(this, 'isSubmitSuccessful');
|
|
260
|
+
observable.ref(this, 'isSubmitting');
|
|
261
|
+
observable.ref(this, 'isValidating');
|
|
262
|
+
observable.ref(this, 'isValid');
|
|
263
|
+
observable.ref(this, 'disabled');
|
|
264
|
+
observable.ref(this, 'submitCount');
|
|
265
|
+
observable.ref(this, 'isReady');
|
|
266
|
+
observable.deep(this, 'defaultValues');
|
|
267
|
+
observable.deep(this, 'dirtyFields');
|
|
268
|
+
observable.deep(this, 'touchedFields');
|
|
269
|
+
observable.deep(this, 'validatingFields');
|
|
270
|
+
observable.deep(this, 'errors');
|
|
271
|
+
action(this, 'updateFormState');
|
|
272
|
+
observable.ref(this, 'originalForm');
|
|
273
|
+
action.bound(this, 'submit');
|
|
274
|
+
action.bound(this, 'reset');
|
|
275
|
+
makeObservable(this);
|
|
72
276
|
this.abortController.signal.addEventListener('abort', () => {
|
|
73
277
|
subscription();
|
|
74
278
|
// @ts-ignore
|
|
75
|
-
this.
|
|
279
|
+
this.originalForm = null;
|
|
76
280
|
// @ts-ignore
|
|
77
281
|
this.data = null;
|
|
78
282
|
});
|
|
79
|
-
computed.struct(this, 'data');
|
|
80
|
-
computed.struct(this, 'state');
|
|
81
|
-
observable.ref(this, 'params');
|
|
82
|
-
observable.ref(this, 'form');
|
|
83
|
-
action.bound(this, 'setParams');
|
|
84
|
-
action.bound(this, 'updateParams');
|
|
85
|
-
action.bound(this, 'syncForm');
|
|
86
|
-
makeObservable(this);
|
|
87
283
|
}
|
|
88
284
|
destroy() {
|
|
89
285
|
this.abortController.abort();
|
|
90
286
|
}
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
287
|
+
/**
|
|
288
|
+
* Method to manually submit form.
|
|
289
|
+
* Used to attach this method to <form /> element
|
|
290
|
+
*
|
|
291
|
+
* @example
|
|
292
|
+
*
|
|
293
|
+
* <form onSubmit={form.submit} />
|
|
294
|
+
*/
|
|
295
|
+
submit(e) {
|
|
296
|
+
return new Promise((resolve, reject) => {
|
|
297
|
+
this.originalForm.handleSubmit((data, event) => {
|
|
298
|
+
this.config.onSubmit?.(data, event);
|
|
299
|
+
resolve(data);
|
|
300
|
+
}, (errors, event) => {
|
|
301
|
+
this.config.onSubmitFailed?.(errors, event);
|
|
302
|
+
reject(errors);
|
|
303
|
+
})(e);
|
|
304
|
+
});
|
|
305
|
+
}
|
|
306
|
+
/**
|
|
307
|
+
* Method to manually reset all form.
|
|
308
|
+
* Used to attach this method to <form /> element
|
|
309
|
+
*
|
|
310
|
+
* @example
|
|
311
|
+
*
|
|
312
|
+
* <form onReset={form.reset} />
|
|
313
|
+
*/
|
|
314
|
+
reset(e) {
|
|
315
|
+
this.resetForm();
|
|
316
|
+
this.config.onReset?.(e);
|
|
317
|
+
}
|
|
318
|
+
updateFormState({ values, errors, ...simpleProperties }) {
|
|
319
|
+
Object.entries(simpleProperties).forEach(([key, value]) => {
|
|
320
|
+
if (value != null) {
|
|
321
|
+
// @ts-ignore
|
|
322
|
+
this[key] = value;
|
|
323
|
+
}
|
|
324
|
+
});
|
|
325
|
+
if (errors) {
|
|
326
|
+
const currentErrorsSet = new Set(Object.keys(this.errors));
|
|
327
|
+
const newErrors = Object.keys(errors);
|
|
328
|
+
for (const errorField of newErrors) {
|
|
329
|
+
if (currentErrorsSet.has(errorField)) {
|
|
330
|
+
currentErrorsSet.delete(errorField);
|
|
331
|
+
// @ts-ignore
|
|
332
|
+
Object.assign(this.errors[errorField], errors[errorField]);
|
|
333
|
+
}
|
|
334
|
+
else {
|
|
335
|
+
// @ts-ignore
|
|
336
|
+
this.errors[errorField] = errors[errorField];
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
currentErrorsSet.forEach((errorField) => {
|
|
340
|
+
// @ts-ignore
|
|
341
|
+
delete this.errors[errorField];
|
|
342
|
+
});
|
|
94
343
|
}
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
344
|
+
else {
|
|
345
|
+
this.errors = {};
|
|
346
|
+
}
|
|
347
|
+
// @ts-ignore
|
|
348
|
+
this.values = values ?? {};
|
|
349
|
+
}
|
|
99
350
|
}
|
|
@@ -20,9 +20,8 @@ export interface MobxFormParams<TFieldValues extends FieldValues = FieldValues,
|
|
|
20
20
|
/**
|
|
21
21
|
* Form reset handler
|
|
22
22
|
*/
|
|
23
|
-
onReset?:
|
|
23
|
+
onReset?: (event: any) => void;
|
|
24
24
|
}
|
|
25
|
-
export type ExtractFormFieldValues<T extends AnyMobxForm> = Exclude<T['
|
|
26
|
-
export type ExtractFormContext<T extends AnyMobxForm> = Exclude<T['params']['context'], undefined | null>;
|
|
25
|
+
export type ExtractFormFieldValues<T extends AnyMobxForm> = Exclude<T['values'], undefined | null>;
|
|
27
26
|
export type ExtractFormFieldOutputValues<T extends AnyMobxForm> = T extends MobxForm<any, any, infer TFieldOutputValues> ? TFieldOutputValues : never;
|
|
28
27
|
//# sourceMappingURL=mobx-form.types.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mobx-form.types.d.ts","sourceRoot":"","sources":["../../src/mobx-form/mobx-form.types.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,WAAW,EACX,kBAAkB,EAClB,aAAa,EACb,YAAY,EACb,MAAM,iBAAiB,CAAC;AAEzB,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAE/C,MAAM,MAAM,WAAW,GAAG,QAAQ,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;AAElD;;GAEG;AACH,MAAM,WAAW,cAAc,CAC7B,YAAY,SAAS,WAAW,GAAG,WAAW,EAC9C,QAAQ,GAAG,GAAG,EACd,kBAAkB,GAAG,YAAY,CACjC,SAAQ,YAAY,CAAC,YAAY,EAAE,QAAQ,EAAE,kBAAkB,CAAC;IAChE;;OAEG;IACH,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B;;OAEG;IACH,QAAQ,CAAC,EAAE,aAAa,CAAC,kBAAkB,CAAC,CAAC;IAC7C;;OAEG;IACH,cAAc,CAAC,EAAE,kBAAkB,CAAC,YAAY,CAAC,CAAC;IAClD;;OAEG;IACH,OAAO,CAAC,EAAE,
|
|
1
|
+
{"version":3,"file":"mobx-form.types.d.ts","sourceRoot":"","sources":["../../src/mobx-form/mobx-form.types.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,WAAW,EACX,kBAAkB,EAClB,aAAa,EACb,YAAY,EACb,MAAM,iBAAiB,CAAC;AAEzB,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAE/C,MAAM,MAAM,WAAW,GAAG,QAAQ,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;AAElD;;GAEG;AACH,MAAM,WAAW,cAAc,CAC7B,YAAY,SAAS,WAAW,GAAG,WAAW,EAC9C,QAAQ,GAAG,GAAG,EACd,kBAAkB,GAAG,YAAY,CACjC,SAAQ,YAAY,CAAC,YAAY,EAAE,QAAQ,EAAE,kBAAkB,CAAC;IAChE;;OAEG;IACH,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B;;OAEG;IACH,QAAQ,CAAC,EAAE,aAAa,CAAC,kBAAkB,CAAC,CAAC;IAC7C;;OAEG;IACH,cAAc,CAAC,EAAE,kBAAkB,CAAC,YAAY,CAAC,CAAC;IAClD;;OAEG;IACH,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,KAAK,IAAI,CAAC;CAChC;AAED,MAAM,MAAM,sBAAsB,CAAC,CAAC,SAAS,WAAW,IAAI,OAAO,CACjE,CAAC,CAAC,QAAQ,CAAC,EACX,SAAS,GAAG,IAAI,CACjB,CAAC;AAEF,MAAM,MAAM,4BAA4B,CAAC,CAAC,SAAS,WAAW,IAC5D,CAAC,SAAS,QAAQ,CAAC,GAAG,EAAE,GAAG,EAAE,MAAM,kBAAkB,CAAC,GAClD,kBAAkB,GAClB,KAAK,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mobx-react-hook-form",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "3.0.0",
|
|
4
4
|
"description": "",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"keywords": [],
|
|
@@ -22,6 +22,7 @@
|
|
|
22
22
|
},
|
|
23
23
|
"dependencies": {
|
|
24
24
|
"disposer-util": "^2.0.0",
|
|
25
|
+
"@types/react": "^18.3.1",
|
|
25
26
|
"linked-abort-controller": "^1.1.0",
|
|
26
27
|
"lodash-es": "^4.17.21",
|
|
27
28
|
"yummies": "^3.0.39"
|
|
@@ -46,11 +47,6 @@
|
|
|
46
47
|
"default": "./mobx-form/index.js",
|
|
47
48
|
"types": "./mobx-form/index.d.ts"
|
|
48
49
|
},
|
|
49
|
-
"./mobx-form/mobx-form-state": {
|
|
50
|
-
"import": "./mobx-form/mobx-form-state.js",
|
|
51
|
-
"default": "./mobx-form/mobx-form-state.js",
|
|
52
|
-
"types": "./mobx-form/mobx-form-state.d.ts"
|
|
53
|
-
},
|
|
54
50
|
"./mobx-form/mobx-form": {
|
|
55
51
|
"import": "./mobx-form/mobx-form.js",
|
|
56
52
|
"default": "./mobx-form/mobx-form.js",
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
import { DeepMap, DeepPartial, FieldErrors, FieldValues, FormState } from 'react-hook-form';
|
|
2
|
-
type FormValues<TFieldValues extends FieldValues> = {
|
|
3
|
-
values: TFieldValues;
|
|
4
|
-
};
|
|
5
|
-
type MobxFormStateUpdate<TFieldValues extends FieldValues> = Omit<Partial<MobxFormState<TFieldValues>>, 'update'>;
|
|
6
|
-
export type MobxFormStateReadonly<TFieldValues extends FieldValues> = Readonly<Omit<MobxFormState<TFieldValues>, 'update'>>;
|
|
7
|
-
export declare class MobxFormState<TFieldValues extends FieldValues = FieldValues> implements FormState<TFieldValues>, FormValues<TFieldValues> {
|
|
8
|
-
values: TFieldValues;
|
|
9
|
-
isDirty: boolean;
|
|
10
|
-
isLoading: boolean;
|
|
11
|
-
isSubmitted: boolean;
|
|
12
|
-
isSubmitSuccessful: boolean;
|
|
13
|
-
isSubmitting: boolean;
|
|
14
|
-
isValidating: boolean;
|
|
15
|
-
isValid: boolean;
|
|
16
|
-
disabled: boolean;
|
|
17
|
-
submitCount: number;
|
|
18
|
-
defaultValues: Readonly<DeepPartial<TFieldValues>> | undefined;
|
|
19
|
-
dirtyFields: Partial<Readonly<DeepMap<DeepPartial<TFieldValues>, boolean>>>;
|
|
20
|
-
touchedFields: Partial<Readonly<DeepMap<DeepPartial<TFieldValues>, boolean>>>;
|
|
21
|
-
validatingFields: Partial<Readonly<DeepMap<DeepPartial<TFieldValues>, boolean>>>;
|
|
22
|
-
errors: FieldErrors<TFieldValues>;
|
|
23
|
-
isReady: boolean;
|
|
24
|
-
constructor(initialState?: MobxFormStateUpdate<TFieldValues>);
|
|
25
|
-
update({ values, errors, ...simpleProperties }: MobxFormStateUpdate<TFieldValues>): void;
|
|
26
|
-
}
|
|
27
|
-
export {};
|
|
28
|
-
//# sourceMappingURL=mobx-form-state.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"mobx-form-state.d.ts","sourceRoot":"","sources":["../../src/mobx-form/mobx-form-state.ts"],"names":[],"mappings":"AAGA,OAAO,EACL,OAAO,EACP,WAAW,EACX,WAAW,EACX,WAAW,EACX,SAAS,EACV,MAAM,iBAAiB,CAAC;AAEzB,KAAK,UAAU,CAAC,YAAY,SAAS,WAAW,IAAI;IAClD,MAAM,EAAE,YAAY,CAAC;CACtB,CAAC;AAEF,KAAK,mBAAmB,CAAC,YAAY,SAAS,WAAW,IAAI,IAAI,CAC/D,OAAO,CAAC,aAAa,CAAC,YAAY,CAAC,CAAC,EACpC,QAAQ,CACT,CAAC;AAEF,MAAM,MAAM,qBAAqB,CAAC,YAAY,SAAS,WAAW,IAAI,QAAQ,CAC5E,IAAI,CAAC,aAAa,CAAC,YAAY,CAAC,EAAE,QAAQ,CAAC,CAC5C,CAAC;AAEF,qBAAa,aAAa,CAAC,YAAY,SAAS,WAAW,GAAG,WAAW,CACvE,YAAW,SAAS,CAAC,YAAY,CAAC,EAAE,UAAU,CAAC,YAAY,CAAC;IAE5D,MAAM,EAAG,YAAY,CAAC;IACtB,OAAO,EAAE,OAAO,CAAS;IACzB,SAAS,EAAE,OAAO,CAAS;IAC3B,WAAW,EAAE,OAAO,CAAS;IAC7B,kBAAkB,EAAE,OAAO,CAAS;IACpC,YAAY,EAAE,OAAO,CAAS;IAC9B,YAAY,EAAE,OAAO,CAAS;IAC9B,OAAO,EAAE,OAAO,CAAS;IACzB,QAAQ,EAAE,OAAO,CAAS;IAC1B,WAAW,EAAE,MAAM,CAAK;IACxB,aAAa,EAAE,QAAQ,CAAC,WAAW,CAAC,YAAY,CAAC,CAAC,GAAG,SAAS,CAAC;IAC/D,WAAW,EAAE,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,WAAW,CAAC,YAAY,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,CACtE;IACL,aAAa,EAAE,OAAO,CACpB,QAAQ,CAAC,OAAO,CAAC,WAAW,CAAC,YAAY,CAAC,EAAE,OAAO,CAAC,CAAC,CACtD,CAAM;IACP,gBAAgB,EAAE,OAAO,CACvB,QAAQ,CAAC,OAAO,CAAC,WAAW,CAAC,YAAY,CAAC,EAAE,OAAO,CAAC,CAAC,CACtD,CAAM;IACP,MAAM,EAAE,WAAW,CAAC,YAAY,CAAC,CAAM;IACvC,OAAO,EAAE,OAAO,CAAS;gBAEb,YAAY,CAAC,EAAE,mBAAmB,CAAC,YAAY,CAAC;IA0B5D,MAAM,CAAC,EACL,MAAM,EACN,MAAM,EACN,GAAG,gBAAgB,EACpB,EAAE,mBAAmB,CAAC,YAAY,CAAC;CAkCrC"}
|
|
@@ -1,76 +0,0 @@
|
|
|
1
|
-
/* eslint-disable @typescript-eslint/no-unused-vars */
|
|
2
|
-
/* eslint-disable @typescript-eslint/ban-ts-comment */
|
|
3
|
-
import { action, makeObservable, observable } from 'mobx';
|
|
4
|
-
export class MobxFormState {
|
|
5
|
-
values;
|
|
6
|
-
isDirty = false;
|
|
7
|
-
isLoading = false;
|
|
8
|
-
isSubmitted = false;
|
|
9
|
-
isSubmitSuccessful = false;
|
|
10
|
-
isSubmitting = false;
|
|
11
|
-
isValidating = false;
|
|
12
|
-
isValid = false;
|
|
13
|
-
disabled = false;
|
|
14
|
-
submitCount = 0;
|
|
15
|
-
defaultValues;
|
|
16
|
-
dirtyFields = {};
|
|
17
|
-
touchedFields = {};
|
|
18
|
-
validatingFields = {};
|
|
19
|
-
errors = {};
|
|
20
|
-
isReady = false;
|
|
21
|
-
constructor(initialState) {
|
|
22
|
-
if (initialState) {
|
|
23
|
-
Object.assign(this, initialState);
|
|
24
|
-
}
|
|
25
|
-
observable.deep(this, 'values');
|
|
26
|
-
observable.ref(this, 'isDirty');
|
|
27
|
-
observable.ref(this, 'isLoading');
|
|
28
|
-
observable.ref(this, 'isSubmitted');
|
|
29
|
-
observable.ref(this, 'isSubmitSuccessful');
|
|
30
|
-
observable.ref(this, 'isSubmitting');
|
|
31
|
-
observable.ref(this, 'isValidating');
|
|
32
|
-
observable.ref(this, 'isValid');
|
|
33
|
-
observable.ref(this, 'disabled');
|
|
34
|
-
observable.ref(this, 'submitCount');
|
|
35
|
-
observable.ref(this, 'isReady');
|
|
36
|
-
observable.deep(this, 'defaultValues');
|
|
37
|
-
observable.deep(this, 'dirtyFields');
|
|
38
|
-
observable.deep(this, 'touchedFields');
|
|
39
|
-
observable.deep(this, 'validatingFields');
|
|
40
|
-
observable.deep(this, 'errors');
|
|
41
|
-
action(this, 'update');
|
|
42
|
-
makeObservable(this);
|
|
43
|
-
}
|
|
44
|
-
update({ values, errors, ...simpleProperties }) {
|
|
45
|
-
Object.entries(simpleProperties).forEach(([key, value]) => {
|
|
46
|
-
if (value != null) {
|
|
47
|
-
// @ts-ignore
|
|
48
|
-
this[key] = value;
|
|
49
|
-
}
|
|
50
|
-
});
|
|
51
|
-
if (errors) {
|
|
52
|
-
const currentErrorsSet = new Set(Object.keys(this.errors));
|
|
53
|
-
const newErrors = Object.keys(errors);
|
|
54
|
-
for (const errorField of newErrors) {
|
|
55
|
-
if (currentErrorsSet.has(errorField)) {
|
|
56
|
-
currentErrorsSet.delete(errorField);
|
|
57
|
-
// @ts-ignore
|
|
58
|
-
Object.assign(this.errors[errorField], errors[errorField]);
|
|
59
|
-
}
|
|
60
|
-
else {
|
|
61
|
-
// @ts-ignore
|
|
62
|
-
this.errors[errorField] = errors[errorField];
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
currentErrorsSet.forEach((errorField) => {
|
|
66
|
-
// @ts-ignore
|
|
67
|
-
delete this.errors[errorField];
|
|
68
|
-
});
|
|
69
|
-
}
|
|
70
|
-
else {
|
|
71
|
-
this.errors = {};
|
|
72
|
-
}
|
|
73
|
-
// @ts-ignore
|
|
74
|
-
this.values = values ?? {};
|
|
75
|
-
}
|
|
76
|
-
}
|