@refinedev/react-hook-form 4.8.14 → 4.8.15

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.
@@ -3,272 +3,270 @@ import get from "lodash/get";
3
3
  import has from "lodash/has";
4
4
 
5
5
  import {
6
- useForm as useHookForm,
7
- UseFormProps as UseHookFormProps,
8
- UseFormReturn,
9
- FieldValues,
10
- UseFormHandleSubmit,
11
- Path,
6
+ useForm as useHookForm,
7
+ UseFormProps as UseHookFormProps,
8
+ UseFormReturn,
9
+ FieldValues,
10
+ UseFormHandleSubmit,
11
+ Path,
12
12
  } from "react-hook-form";
13
13
  import {
14
- BaseRecord,
15
- HttpError,
16
- useForm as useFormCore,
17
- useWarnAboutChange,
18
- UseFormProps as UseFormCoreProps,
19
- UseFormReturnType as UseFormReturnTypeCore,
20
- useTranslate,
21
- useRefineContext,
22
- flattenObjectKeys,
14
+ BaseRecord,
15
+ HttpError,
16
+ useForm as useFormCore,
17
+ useWarnAboutChange,
18
+ UseFormProps as UseFormCoreProps,
19
+ UseFormReturnType as UseFormReturnTypeCore,
20
+ useTranslate,
21
+ useRefineContext,
22
+ flattenObjectKeys,
23
23
  } from "@refinedev/core";
24
24
 
25
25
  export type UseFormReturnType<
26
- TQueryFnData extends BaseRecord = BaseRecord,
27
- TError extends HttpError = HttpError,
28
- TVariables extends FieldValues = FieldValues,
29
- TContext extends object = {},
30
- TData extends BaseRecord = TQueryFnData,
31
- TResponse extends BaseRecord = TData,
32
- TResponseError extends HttpError = TError,
26
+ TQueryFnData extends BaseRecord = BaseRecord,
27
+ TError extends HttpError = HttpError,
28
+ TVariables extends FieldValues = FieldValues,
29
+ TContext extends object = {},
30
+ TData extends BaseRecord = TQueryFnData,
31
+ TResponse extends BaseRecord = TData,
32
+ TResponseError extends HttpError = TError,
33
33
  > = UseFormReturn<TVariables, TContext> & {
34
- refineCore: UseFormReturnTypeCore<
35
- TQueryFnData,
36
- TError,
37
- TVariables,
38
- TData,
39
- TResponse,
40
- TResponseError
41
- >;
42
- saveButtonProps: {
43
- disabled: boolean;
44
- onClick: (e: React.BaseSyntheticEvent) => void;
45
- };
34
+ refineCore: UseFormReturnTypeCore<
35
+ TQueryFnData,
36
+ TError,
37
+ TVariables,
38
+ TData,
39
+ TResponse,
40
+ TResponseError
41
+ >;
42
+ saveButtonProps: {
43
+ disabled: boolean;
44
+ onClick: (e: React.BaseSyntheticEvent) => void;
45
+ };
46
46
  };
47
47
 
48
48
  export type UseFormProps<
49
- TQueryFnData extends BaseRecord = BaseRecord,
50
- TError extends HttpError = HttpError,
51
- TVariables extends FieldValues = FieldValues,
52
- TContext extends object = {},
53
- TData extends BaseRecord = TQueryFnData,
54
- TResponse extends BaseRecord = TData,
55
- TResponseError extends HttpError = TError,
49
+ TQueryFnData extends BaseRecord = BaseRecord,
50
+ TError extends HttpError = HttpError,
51
+ TVariables extends FieldValues = FieldValues,
52
+ TContext extends object = {},
53
+ TData extends BaseRecord = TQueryFnData,
54
+ TResponse extends BaseRecord = TData,
55
+ TResponseError extends HttpError = TError,
56
56
  > = {
57
- /**
58
- * Configuration object for the core of the [useForm](/docs/api-reference/core/hooks/useForm/)
59
- * @type [`UseFormCoreProps<TQueryFnData, TError, TVariables, TData, TResponse, TResponseError>`](/docs/api-reference/core/hooks/useForm/#properties)
60
- */
61
- refineCoreProps?: UseFormCoreProps<
62
- TQueryFnData,
63
- TError,
64
- TVariables,
65
- TData,
66
- TResponse,
67
- TResponseError
68
- >;
69
- /**
70
- * When you have unsaved changes and try to leave the current page, **refine** shows a confirmation modal box.
71
- * @default `false*`
72
- */
73
- warnWhenUnsavedChanges?: boolean;
74
- /**
75
- * Disables server-side validation
76
- * @default false
77
- * @see {@link https://refine.dev/docs/advanced-tutorials/forms/server-side-form-validation/}
78
- */
79
- disableServerSideValidation?: boolean;
80
- } & UseHookFormProps<TVariables, TContext>;
81
-
82
- export const useForm = <
83
- TQueryFnData extends BaseRecord = BaseRecord,
84
- TError extends HttpError = HttpError,
85
- TVariables extends FieldValues = FieldValues,
86
- TContext extends object = {},
87
- TData extends BaseRecord = TQueryFnData,
88
- TResponse extends BaseRecord = TData,
89
- TResponseError extends HttpError = TError,
90
- >({
91
- refineCoreProps,
92
- warnWhenUnsavedChanges: warnWhenUnsavedChangesProp,
93
- disableServerSideValidation: disableServerSideValidationProp = false,
94
- ...rest
95
- }: UseFormProps<
57
+ /**
58
+ * Configuration object for the core of the [useForm](/docs/api-reference/core/hooks/useForm/)
59
+ * @type [`UseFormCoreProps<TQueryFnData, TError, TVariables, TData, TResponse, TResponseError>`](/docs/api-reference/core/hooks/useForm/#properties)
60
+ */
61
+ refineCoreProps?: UseFormCoreProps<
96
62
  TQueryFnData,
97
63
  TError,
98
64
  TVariables,
99
- TContext,
100
65
  TData,
101
66
  TResponse,
102
67
  TResponseError
68
+ >;
69
+ /**
70
+ * When you have unsaved changes and try to leave the current page, **refine** shows a confirmation modal box.
71
+ * @default `false*`
72
+ */
73
+ warnWhenUnsavedChanges?: boolean;
74
+ /**
75
+ * Disables server-side validation
76
+ * @default false
77
+ * @see {@link https://refine.dev/docs/advanced-tutorials/forms/server-side-form-validation/}
78
+ */
79
+ disableServerSideValidation?: boolean;
80
+ } & UseHookFormProps<TVariables, TContext>;
81
+
82
+ export const useForm = <
83
+ TQueryFnData extends BaseRecord = BaseRecord,
84
+ TError extends HttpError = HttpError,
85
+ TVariables extends FieldValues = FieldValues,
86
+ TContext extends object = {},
87
+ TData extends BaseRecord = TQueryFnData,
88
+ TResponse extends BaseRecord = TData,
89
+ TResponseError extends HttpError = TError,
90
+ >({
91
+ refineCoreProps,
92
+ warnWhenUnsavedChanges: warnWhenUnsavedChangesProp,
93
+ disableServerSideValidation: disableServerSideValidationProp = false,
94
+ ...rest
95
+ }: UseFormProps<
96
+ TQueryFnData,
97
+ TError,
98
+ TVariables,
99
+ TContext,
100
+ TData,
101
+ TResponse,
102
+ TResponseError
103
103
  > = {}): UseFormReturnType<
104
+ TQueryFnData,
105
+ TError,
106
+ TVariables,
107
+ TContext,
108
+ TData,
109
+ TResponse,
110
+ TResponseError
111
+ > => {
112
+ const { options } = useRefineContext();
113
+ const disableServerSideValidation =
114
+ options?.disableServerSideValidation || disableServerSideValidationProp;
115
+
116
+ const translate = useTranslate();
117
+
118
+ const { warnWhenUnsavedChanges: warnWhenUnsavedChangesRefine, setWarnWhen } =
119
+ useWarnAboutChange();
120
+ const warnWhenUnsavedChanges =
121
+ warnWhenUnsavedChangesProp ?? warnWhenUnsavedChangesRefine;
122
+
123
+ const useHookFormResult = useHookForm<TVariables, TContext>({
124
+ ...rest,
125
+ });
126
+
127
+ const {
128
+ watch,
129
+ setValue,
130
+ getValues,
131
+ handleSubmit: handleSubmitReactHookForm,
132
+ setError,
133
+ } = useHookFormResult;
134
+
135
+ const useFormCoreResult = useFormCore<
104
136
  TQueryFnData,
105
137
  TError,
106
138
  TVariables,
107
- TContext,
108
139
  TData,
109
140
  TResponse,
110
141
  TResponseError
111
- > => {
112
- const { options } = useRefineContext();
113
- const disableServerSideValidation =
114
- options?.disableServerSideValidation || disableServerSideValidationProp;
142
+ >({
143
+ ...refineCoreProps,
144
+ onMutationError: (error, _variables, _context) => {
145
+ if (disableServerSideValidation) {
146
+ refineCoreProps?.onMutationError?.(error, _variables, _context);
147
+ return;
148
+ }
149
+
150
+ const errors = error?.errors;
151
+
152
+ for (const key in errors) {
153
+ // when the key is not registered in the form, react-hook-form not working
154
+ const isKeyInVariables = Object.keys(
155
+ flattenObjectKeys(_variables),
156
+ ).includes(key);
157
+
158
+ if (!isKeyInVariables) {
159
+ continue;
160
+ }
115
161
 
116
- const translate = useTranslate();
162
+ const fieldError = errors[key];
117
163
 
118
- const {
119
- warnWhenUnsavedChanges: warnWhenUnsavedChangesRefine,
120
- setWarnWhen,
121
- } = useWarnAboutChange();
122
- const warnWhenUnsavedChanges =
123
- warnWhenUnsavedChangesProp ?? warnWhenUnsavedChangesRefine;
164
+ let newError = "";
124
165
 
125
- const useHookFormResult = useHookForm<TVariables, TContext>({
126
- ...rest,
127
- });
166
+ if (Array.isArray(fieldError)) {
167
+ newError = fieldError.join(" ");
168
+ }
128
169
 
129
- const {
130
- watch,
131
- setValue,
132
- getValues,
133
- handleSubmit: handleSubmitReactHookForm,
134
- setError,
135
- } = useHookFormResult;
136
-
137
- const useFormCoreResult = useFormCore<
138
- TQueryFnData,
139
- TError,
140
- TVariables,
141
- TData,
142
- TResponse,
143
- TResponseError
144
- >({
145
- ...refineCoreProps,
146
- onMutationError: (error, _variables, _context) => {
147
- if (disableServerSideValidation) {
148
- refineCoreProps?.onMutationError?.(error, _variables, _context);
149
- return;
150
- }
151
-
152
- const errors = error?.errors;
153
-
154
- for (const key in errors) {
155
- // when the key is not registered in the form, react-hook-form not working
156
- const isKeyInVariables = Object.keys(
157
- flattenObjectKeys(_variables),
158
- ).includes(key);
159
-
160
- if (!isKeyInVariables) {
161
- continue;
162
- }
163
-
164
- const fieldError = errors[key];
165
-
166
- let newError = "";
167
-
168
- if (Array.isArray(fieldError)) {
169
- newError = fieldError.join(" ");
170
- }
171
-
172
- if (typeof fieldError === "string") {
173
- newError = fieldError;
174
- }
175
-
176
- if (typeof fieldError === "boolean" && fieldError) {
177
- newError = "Field is not valid.";
178
- }
179
-
180
- if (typeof fieldError === "object" && "key" in fieldError) {
181
- const translatedMessage = translate(
182
- fieldError.key,
183
- fieldError.message,
184
- );
185
-
186
- newError = translatedMessage;
187
- }
188
-
189
- setError(key as Path<TVariables>, {
190
- message: newError,
191
- });
192
- }
193
-
194
- refineCoreProps?.onMutationError?.(error, _variables, _context);
195
- },
196
- });
170
+ if (typeof fieldError === "string") {
171
+ newError = fieldError;
172
+ }
197
173
 
198
- const { queryResult, onFinish, formLoading, onFinishAutoSave } =
199
- useFormCoreResult;
200
-
201
- useEffect(() => {
202
- const data = queryResult?.data?.data;
203
- if (!data) return;
204
-
205
- /**
206
- * get registered fields from react-hook-form
207
- */
208
- const registeredFields = Object.keys(flattenObjectKeys(getValues()));
209
-
210
- /**
211
- * set values from query result as default values
212
- */
213
- registeredFields.forEach((path) => {
214
- const hasValue = has(data, path);
215
- const dataValue = get(data, path);
216
-
217
- /**
218
- * set value if the path exists in the query result even if the value is null
219
- */
220
- if (hasValue) {
221
- setValue(path as Path<TVariables>, dataValue);
222
- }
223
- });
224
- }, [queryResult?.data, setValue, getValues]);
174
+ if (typeof fieldError === "boolean" && fieldError) {
175
+ newError = "Field is not valid.";
176
+ }
225
177
 
226
- useEffect(() => {
227
- const subscription = watch((values: any, { type }: { type?: any }) => {
228
- if (type === "change") {
229
- onValuesChange(values);
230
- }
231
- });
232
- return () => subscription.unsubscribe();
233
- }, [watch]);
178
+ if (typeof fieldError === "object" && "key" in fieldError) {
179
+ const translatedMessage = translate(
180
+ fieldError.key,
181
+ fieldError.message,
182
+ );
234
183
 
235
- const onValuesChange = (changeValues: TVariables) => {
236
- if (warnWhenUnsavedChanges) {
237
- setWarnWhen(true);
184
+ newError = translatedMessage;
238
185
  }
239
186
 
240
- if (refineCoreProps?.autoSave) {
241
- setWarnWhen(false);
187
+ setError(key as Path<TVariables>, {
188
+ message: newError,
189
+ });
190
+ }
242
191
 
243
- const onFinishProps = refineCoreProps.autoSave?.onFinish;
192
+ refineCoreProps?.onMutationError?.(error, _variables, _context);
193
+ },
194
+ });
244
195
 
245
- if (onFinishProps) {
246
- return onFinishAutoSave(onFinishProps(changeValues));
247
- }
196
+ const { queryResult, onFinish, formLoading, onFinishAutoSave } =
197
+ useFormCoreResult;
248
198
 
249
- return onFinishAutoSave(changeValues);
250
- }
199
+ useEffect(() => {
200
+ const data = queryResult?.data?.data;
201
+ if (!data) return;
251
202
 
252
- return changeValues;
253
- };
203
+ /**
204
+ * get registered fields from react-hook-form
205
+ */
206
+ const registeredFields = Object.keys(flattenObjectKeys(getValues()));
254
207
 
255
- const handleSubmit: UseFormHandleSubmit<TVariables> =
256
- (onValid, onInvalid) => async (e) => {
257
- setWarnWhen(false);
258
- return handleSubmitReactHookForm(onValid, onInvalid)(e);
259
- };
260
-
261
- const saveButtonProps = {
262
- disabled: formLoading,
263
- onClick: (e: React.BaseSyntheticEvent) => {
264
- handleSubmit(onFinish, () => false)(e);
265
- },
266
- };
208
+ /**
209
+ * set values from query result as default values
210
+ */
211
+ registeredFields.forEach((path) => {
212
+ const hasValue = has(data, path);
213
+ const dataValue = get(data, path);
214
+
215
+ /**
216
+ * set value if the path exists in the query result even if the value is null
217
+ */
218
+ if (hasValue) {
219
+ setValue(path as Path<TVariables>, dataValue);
220
+ }
221
+ });
222
+ }, [queryResult?.data, setValue, getValues]);
223
+
224
+ useEffect(() => {
225
+ const subscription = watch((values: any, { type }: { type?: any }) => {
226
+ if (type === "change") {
227
+ onValuesChange(values);
228
+ }
229
+ });
230
+ return () => subscription.unsubscribe();
231
+ }, [watch]);
232
+
233
+ const onValuesChange = (changeValues: TVariables) => {
234
+ if (warnWhenUnsavedChanges) {
235
+ setWarnWhen(true);
236
+ }
267
237
 
268
- return {
269
- ...useHookFormResult,
270
- handleSubmit,
271
- refineCore: useFormCoreResult,
272
- saveButtonProps,
238
+ if (refineCoreProps?.autoSave) {
239
+ setWarnWhen(false);
240
+
241
+ const onFinishProps = refineCoreProps.autoSave?.onFinish;
242
+
243
+ if (onFinishProps) {
244
+ return onFinishAutoSave(onFinishProps(changeValues));
245
+ }
246
+
247
+ return onFinishAutoSave(changeValues);
248
+ }
249
+
250
+ return changeValues;
251
+ };
252
+
253
+ const handleSubmit: UseFormHandleSubmit<TVariables> =
254
+ (onValid, onInvalid) => async (e) => {
255
+ setWarnWhen(false);
256
+ return handleSubmitReactHookForm(onValid, onInvalid)(e);
273
257
  };
258
+
259
+ const saveButtonProps = {
260
+ disabled: formLoading,
261
+ onClick: (e: React.BaseSyntheticEvent) => {
262
+ handleSubmit(onFinish, () => false)(e);
263
+ },
264
+ };
265
+
266
+ return {
267
+ ...useHookFormResult,
268
+ handleSubmit,
269
+ refineCore: useFormCoreResult,
270
+ saveButtonProps,
271
+ };
274
272
  };