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.
@@ -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?: any[];
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 { value, setData, getCacheData, getFormValues } = useFormStore(
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 (!value) {
482
- if (!internalInitValue) {
483
- if (!isNil(initialValue)) {
484
- console.log("On init data", initialValue);
485
- onInitData(initialValue);
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
- }, [internalInitValue]);
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;
@@ -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 default function Form({
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
- setInitData: state.setFormInitData,
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
- setInitData(formName, initialValues);
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>(formNameOrFormInstance?: string | PublicFormInstance<T>) {
403
+ export function useForm<T = any>(
404
+ formNameOrFormInstance?: string | PublicFormInstance<T>,
405
+ ) {
367
406
  const targetFormName =
368
- typeof formNameOrFormInstance === "object" && formNameOrFormInstance !== null
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>(name: keyof T & string, formNameOrFormInstance?: string | PublicFormInstance<T>) {
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
- }: { formNameOrFormInstance?: string | PublicFormInstance<T>; triggerWhenChange?: boolean; mapFn?: (v: any, prev: any) => any } ) {
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>(formNameOrFormInstance?: string | PublicFormInstance<T>) => {
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) => {