react-form-manage 1.0.6-beta.1 → 1.0.6-beta.3
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/CHANGELOG.md +15 -0
- package/dist/components/Form/FormItem.d.ts +12 -17
- package/dist/components/Form/FormList.d.ts +23 -7
- package/dist/components/Form/InputWrapper.d.ts +10 -5
- package/dist/hooks/useFormItemControl.d.ts +2 -1
- package/dist/hooks/useFormItemControl.js +25 -10
- package/dist/index.d.ts +5 -5
- package/dist/providers/Form.d.ts +16 -10
- package/dist/providers/Form.js +21 -4
- package/dist/stores/formStore.d.ts +12 -9
- package/dist/stores/formStore.js +1 -1
- package/dist/types/public.d.ts +37 -9
- package/package.json +1 -1
- package/src/App.tsx +74 -3
- package/src/components/Form/FormItem.tsx +15 -2
- package/src/components/Form/FormList.tsx +10 -1
- package/src/components/Form/InputWrapper.tsx +8 -1
- package/src/hooks/useFormItemControl.ts +39 -10
- package/src/index.ts +10 -3
- package/src/providers/Form.tsx +59 -10
- package/src/stores/formStore.ts +286 -284
- package/src/types/public.ts +37 -9
|
@@ -25,6 +25,7 @@ import {
|
|
|
25
25
|
} from "../stores/formStore";
|
|
26
26
|
|
|
27
27
|
import type { FormInstance } from "../stores/formStore";
|
|
28
|
+
import type { ValidationRule } from "../types/public";
|
|
28
29
|
|
|
29
30
|
type AnyObject = Record<string, any>;
|
|
30
31
|
|
|
@@ -34,7 +35,7 @@ interface UseFormItemControlProps {
|
|
|
34
35
|
name?: string;
|
|
35
36
|
initialValue?: any;
|
|
36
37
|
formItemId?: string;
|
|
37
|
-
rules?:
|
|
38
|
+
rules?: ValidationRule[];
|
|
38
39
|
elementRef?: RefObject<any> | null;
|
|
39
40
|
}
|
|
40
41
|
|
|
@@ -59,7 +60,14 @@ export default function useFormItemControl<T = any>({
|
|
|
59
60
|
elementRef,
|
|
60
61
|
}: UseFormItemControlProps): UseFormItemControlReturn {
|
|
61
62
|
const contextForm = useFormContext();
|
|
62
|
-
const {
|
|
63
|
+
const {
|
|
64
|
+
value,
|
|
65
|
+
setData,
|
|
66
|
+
getCacheData,
|
|
67
|
+
getFormValues,
|
|
68
|
+
getFormState,
|
|
69
|
+
isStateInitied,
|
|
70
|
+
} = useFormStore(
|
|
63
71
|
useShallow((state) => {
|
|
64
72
|
return {
|
|
65
73
|
value: get(
|
|
@@ -69,6 +77,11 @@ export default function useFormItemControl<T = any>({
|
|
|
69
77
|
setData: state.setData,
|
|
70
78
|
getCacheData: state.getCacheData,
|
|
71
79
|
getFormValues: state.getFormValues,
|
|
80
|
+
getFormState: state.getFormState,
|
|
81
|
+
isStateInitied:
|
|
82
|
+
state.formStates?.[
|
|
83
|
+
formName || form?.formName || contextForm?.formName
|
|
84
|
+
]?.isInitied,
|
|
72
85
|
};
|
|
73
86
|
}),
|
|
74
87
|
);
|
|
@@ -130,6 +143,7 @@ export default function useFormItemControl<T = any>({
|
|
|
130
143
|
name,
|
|
131
144
|
value,
|
|
132
145
|
);
|
|
146
|
+
onChange(value, { notTriggerDirty: true });
|
|
133
147
|
};
|
|
134
148
|
|
|
135
149
|
const onFocus = () => {
|
|
@@ -283,6 +297,16 @@ export default function useFormItemControl<T = any>({
|
|
|
283
297
|
}
|
|
284
298
|
}
|
|
285
299
|
|
|
300
|
+
// Custom pattern
|
|
301
|
+
if (r.pattern && !r.pattern.test(fieldValue || "")) {
|
|
302
|
+
listErrors.push({
|
|
303
|
+
ruleName,
|
|
304
|
+
message: r.message,
|
|
305
|
+
});
|
|
306
|
+
|
|
307
|
+
return;
|
|
308
|
+
}
|
|
309
|
+
|
|
286
310
|
// Password
|
|
287
311
|
if (r.isPassword && !IS_PASSWORD_REGEX.test(fieldValue)) {
|
|
288
312
|
// tempMessage.push(IS_PASSWORD_INVALID_MESSAGE);
|
|
@@ -478,17 +502,22 @@ export default function useFormItemControl<T = any>({
|
|
|
478
502
|
// console.log("Init item value: ", name, value, internalInitValue);
|
|
479
503
|
// console.log("internalInitValue: ", internalInitValue);
|
|
480
504
|
|
|
481
|
-
if (
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
505
|
+
if (isStateInitied) {
|
|
506
|
+
// console.log("Skip set init data when form is resetting");
|
|
507
|
+
|
|
508
|
+
if (isNil(value)) {
|
|
509
|
+
if (isNil(internalInitValue)) {
|
|
510
|
+
if (isNil(initialValue)) {
|
|
511
|
+
console.log("On init data", initialValue);
|
|
512
|
+
onInitData(initialValue);
|
|
513
|
+
}
|
|
514
|
+
} else {
|
|
515
|
+
onChange(internalInitValue, { notTriggerDirty: true });
|
|
486
516
|
}
|
|
487
|
-
} else {
|
|
488
|
-
onChange(internalInitValue);
|
|
489
517
|
}
|
|
518
|
+
return;
|
|
490
519
|
}
|
|
491
|
-
}, [
|
|
520
|
+
}, [isStateInitied]);
|
|
492
521
|
|
|
493
522
|
useEffect(() => {
|
|
494
523
|
if (!listener) {
|
package/src/index.ts
CHANGED
|
@@ -3,12 +3,14 @@ import Form, {
|
|
|
3
3
|
useWatch,
|
|
4
4
|
useSubmitDataWatch,
|
|
5
5
|
useFormStateWatch,
|
|
6
|
+
type FormProps,
|
|
7
|
+
type ValidationRule,
|
|
6
8
|
} from "./providers/Form";
|
|
7
9
|
|
|
8
|
-
import FormItem from "./components/Form/FormItem";
|
|
9
|
-
import FormList from "./components/Form/FormList";
|
|
10
|
+
import FormItem, { type FormItemProps } from "./components/Form/FormItem";
|
|
11
|
+
import FormList, { type FormListProps } from "./components/Form/FormList";
|
|
10
12
|
import Input from "./components/Input";
|
|
11
|
-
import InputWrapper from "./components/Form/InputWrapper";
|
|
13
|
+
import InputWrapper, { type InputWrapperProps } from "./components/Form/InputWrapper";
|
|
12
14
|
|
|
13
15
|
import useFormItemControl from "./hooks/useFormItemControl";
|
|
14
16
|
import useFormListControl from "./hooks/useFormListControl";
|
|
@@ -25,6 +27,11 @@ export {
|
|
|
25
27
|
useWatch,
|
|
26
28
|
useSubmitDataWatch,
|
|
27
29
|
useFormStateWatch,
|
|
30
|
+
type FormProps,
|
|
31
|
+
type FormItemProps,
|
|
32
|
+
type FormListProps,
|
|
33
|
+
type InputWrapperProps,
|
|
34
|
+
type ValidationRule,
|
|
28
35
|
};
|
|
29
36
|
|
|
30
37
|
export default Form;
|
package/src/providers/Form.tsx
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { cloneDeep, get, isEqual, last, set, uniq } from "lodash";
|
|
2
2
|
import { useTask } from "minh-custom-hooks-release";
|
|
3
|
+
import type { ComponentType, FormHTMLAttributes, ReactNode } from "react";
|
|
3
4
|
import { createContext, useContext, useEffect, useState } from "react";
|
|
4
5
|
import { flushSync } from "react-dom";
|
|
5
6
|
import { useShallow } from "zustand/react/shallow"; // Import useShallow
|
|
@@ -7,10 +8,28 @@ import FormCleanUp from "../components/Form/FormCleanUp";
|
|
|
7
8
|
import { useFormListeners, useFormStore } from "../stores/formStore";
|
|
8
9
|
import type { PublicFormInstance } from "../types/public";
|
|
9
10
|
import { getAllNoneObjStringPath } from "../utils/obj.util";
|
|
11
|
+
export type { ValidationRule } from "../types/public";
|
|
10
12
|
|
|
11
13
|
export const FormContext = createContext(null);
|
|
12
14
|
|
|
13
|
-
export
|
|
15
|
+
export interface FormProps<T = any> extends Omit<
|
|
16
|
+
FormHTMLAttributes<HTMLFormElement>,
|
|
17
|
+
"onSubmit"
|
|
18
|
+
> {
|
|
19
|
+
children: ReactNode;
|
|
20
|
+
formName: string;
|
|
21
|
+
initialValues?: T;
|
|
22
|
+
onFinish?: (values: T, allValues?: any) => void | Promise<void>;
|
|
23
|
+
onReject?: (errorFields: any[]) => void | Promise<void>;
|
|
24
|
+
onFinally?: (result: {
|
|
25
|
+
errorsField: any[];
|
|
26
|
+
values: T;
|
|
27
|
+
withUnRegisteredValues: any;
|
|
28
|
+
}) => void | Promise<void>;
|
|
29
|
+
FormElement?: ComponentType<any>;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export default function Form<T = any>({
|
|
14
33
|
children,
|
|
15
34
|
formName,
|
|
16
35
|
initialValues,
|
|
@@ -19,8 +38,9 @@ export default function Form({
|
|
|
19
38
|
onFinally,
|
|
20
39
|
FormElement,
|
|
21
40
|
...props
|
|
22
|
-
}) {
|
|
41
|
+
}: FormProps<T>) {
|
|
23
42
|
const {
|
|
43
|
+
appInitValue,
|
|
24
44
|
getFormItemValue,
|
|
25
45
|
setInitData,
|
|
26
46
|
setData,
|
|
@@ -34,7 +54,8 @@ export default function Form({
|
|
|
34
54
|
clearFormState,
|
|
35
55
|
} = useFormStore(
|
|
36
56
|
useShallow((state) => ({
|
|
37
|
-
|
|
57
|
+
appInitValue: state.initialValues,
|
|
58
|
+
setInitData: state.setInitData,
|
|
38
59
|
getFormValues: state.getFormValues,
|
|
39
60
|
setFormState: state.setFormState,
|
|
40
61
|
setFormInstance: state.setFormInstance,
|
|
@@ -143,7 +164,7 @@ export default function Form({
|
|
|
143
164
|
const formValues = getFormValues(formName);
|
|
144
165
|
|
|
145
166
|
const resultValues = cloneDeep(formValues);
|
|
146
|
-
const cleanValues = {};
|
|
167
|
+
const cleanValues = {} as T;
|
|
147
168
|
uniq(listeners, (l) => l.name).forEach((l) => {
|
|
148
169
|
set(cleanValues, l.name, get(resultValues, l.name));
|
|
149
170
|
});
|
|
@@ -292,7 +313,19 @@ export default function Form({
|
|
|
292
313
|
};
|
|
293
314
|
|
|
294
315
|
useEffect(() => {
|
|
295
|
-
|
|
316
|
+
// set initial values
|
|
317
|
+
if (initialValues) {
|
|
318
|
+
const allStringPath = getAllNoneObjStringPath(initialValues);
|
|
319
|
+
allStringPath.forEach((p) => {
|
|
320
|
+
// console.log(
|
|
321
|
+
// "Set initial value for form",
|
|
322
|
+
// formName,
|
|
323
|
+
// p,
|
|
324
|
+
// get(initialValues, p),
|
|
325
|
+
// );
|
|
326
|
+
setInitData(formName, p, get(initialValues, p));
|
|
327
|
+
});
|
|
328
|
+
}
|
|
296
329
|
setFormState({
|
|
297
330
|
formName,
|
|
298
331
|
isInitied: true,
|
|
@@ -319,6 +352,10 @@ export default function Form({
|
|
|
319
352
|
};
|
|
320
353
|
}, []);
|
|
321
354
|
|
|
355
|
+
// useEffect(() => {
|
|
356
|
+
// // console.log("Form appInitValue changed", appInitValue);
|
|
357
|
+
// }, [appInitValue]);
|
|
358
|
+
|
|
322
359
|
return (
|
|
323
360
|
<FormContext.Provider
|
|
324
361
|
value={{
|
|
@@ -363,9 +400,12 @@ export function useFormContext() {
|
|
|
363
400
|
return c;
|
|
364
401
|
}
|
|
365
402
|
|
|
366
|
-
export function useForm<T = any>(
|
|
403
|
+
export function useForm<T = any>(
|
|
404
|
+
formNameOrFormInstance?: string | PublicFormInstance<T>,
|
|
405
|
+
) {
|
|
367
406
|
const targetFormName =
|
|
368
|
-
typeof formNameOrFormInstance === "object" &&
|
|
407
|
+
typeof formNameOrFormInstance === "object" &&
|
|
408
|
+
formNameOrFormInstance !== null
|
|
369
409
|
? (formNameOrFormInstance as PublicFormInstance<T>).formName
|
|
370
410
|
: (formNameOrFormInstance as string | undefined);
|
|
371
411
|
|
|
@@ -376,7 +416,10 @@ export function useForm<T = any>(formNameOrFormInstance?: string | PublicFormIns
|
|
|
376
416
|
return [formInstance];
|
|
377
417
|
}
|
|
378
418
|
|
|
379
|
-
export function useWatch<T = any>(
|
|
419
|
+
export function useWatch<T = any>(
|
|
420
|
+
name: keyof T & string,
|
|
421
|
+
formNameOrFormInstance?: string | PublicFormInstance<T>,
|
|
422
|
+
) {
|
|
380
423
|
const [formInstance] = useForm<T>(formNameOrFormInstance as any);
|
|
381
424
|
|
|
382
425
|
const value = useFormStore((state) => {
|
|
@@ -393,7 +436,11 @@ export function useSubmitDataWatch<T = any>({
|
|
|
393
436
|
formNameOrFormInstance,
|
|
394
437
|
triggerWhenChange = false,
|
|
395
438
|
mapFn,
|
|
396
|
-
}: {
|
|
439
|
+
}: {
|
|
440
|
+
formNameOrFormInstance?: string | PublicFormInstance<T>;
|
|
441
|
+
triggerWhenChange?: boolean;
|
|
442
|
+
mapFn?: (v: any, prev: any) => any;
|
|
443
|
+
}) {
|
|
397
444
|
const [formInstance] = useForm<T>(formNameOrFormInstance as any);
|
|
398
445
|
|
|
399
446
|
const value = useFormStore((state) => {
|
|
@@ -413,7 +460,9 @@ export function useSubmitDataWatch<T = any>({
|
|
|
413
460
|
return submitData as T | undefined;
|
|
414
461
|
}
|
|
415
462
|
|
|
416
|
-
export const useFormStateWatch = <T = any
|
|
463
|
+
export const useFormStateWatch = <T = any,>(
|
|
464
|
+
formNameOrFormInstance?: string | PublicFormInstance<T>,
|
|
465
|
+
) => {
|
|
417
466
|
const [formInstance] = useForm<T>(formNameOrFormInstance as any);
|
|
418
467
|
|
|
419
468
|
const formState = useFormStore((state) => {
|