diff --git a/.changeset/honest-roses-float.md b/.changeset/honest-roses-float.md new file mode 100644 index 00000000..b53e1384 --- /dev/null +++ b/.changeset/honest-roses-float.md @@ -0,0 +1,5 @@ +--- +"react-cool-form": patch +--- + +feat(useForm): add ignoreFields config diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 6f537304..8c9c0945 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -15,7 +15,7 @@ on: # │ │ │ │ │ # │ │ │ │ │ # * * * * * - - cron: "0 12 * * 0" + - cron: "0 6 * * 0" jobs: analyze: diff --git a/examples/src/BasicForm/index.tsx b/examples/src/BasicForm/index.tsx index 3b7d4acd..552626b2 100644 --- a/examples/src/BasicForm/index.tsx +++ b/examples/src/BasicForm/index.tsx @@ -73,6 +73,7 @@ export default (): JSX.Element => { initialValues, // validateOnChange: false, // validateOnBlur: false, + ignoreFields: ["text.nest", "number"], // validate: async (values, set) => { // let errors: any = { text: { nest: "" } }; diff --git a/src/index.ts b/src/index.ts index f114cfd3..ae1d4d56 100644 --- a/src/index.ts +++ b/src/index.ts @@ -29,6 +29,7 @@ import { import useLatest from "./useLatest"; import useFormState from "./useFormState"; import { + arrayToObject, deepMerge, get, isArray, @@ -92,6 +93,7 @@ export function useForm({ validate, validateOnChange = true, validateOnBlur = true, + ignoreFields = [], onReset, onSubmit, onError, @@ -104,7 +106,7 @@ export function useForm({ const onResetRef = useLatest(onReset); const onSubmitRef = useLatest(onSubmit); const onErrorRef = useLatest(onError); - const controllersRef = useRef({}); + const ignoreFieldsRef = useRef(arrayToObject(ignoreFields)); const changedFieldRef = useRef(); const { stateRef, @@ -114,7 +116,7 @@ export function useForm({ } = useFormState(initialValues, debug); const setDomValue = useCallback((name: string, value: any) => { - if (controllersRef.current[name] || !fieldsRef.current[name]) return; + if (ignoreFieldsRef.current[name] || !fieldsRef.current[name]) return; const { field, options } = fieldsRef.current[name]; @@ -157,7 +159,7 @@ export function useForm({ const validateRef = useCallback>( (validate) => (field) => { - if (field?.name && !controllersRef.current[field.name]) + if (field?.name && !ignoreFieldsRef.current[field.name]) fieldValidatorsRef.current[field.name] = validate; }, [] @@ -540,7 +542,7 @@ export function useForm({ return {}; } - controllersRef.current[name] = true; + ignoreFieldsRef.current[name] = true; if (validate) fieldValidatorsRef.current[name] = validate; return { @@ -607,7 +609,7 @@ export function useForm({ return; } - if (fieldsRef.current[name] && !controllersRef.current[name]) + if (fieldsRef.current[name] && !ignoreFieldsRef.current[name]) handleFieldChange(field); }; @@ -620,7 +622,7 @@ export function useForm({ const { name } = target as FieldElement; - if (fieldsRef.current[name] && !controllersRef.current[name]) + if (fieldsRef.current[name] && !ignoreFieldsRef.current[name]) setFieldTouchedIfNeeded(name); }; diff --git a/src/types/index.ts b/src/types/index.ts index 8df68093..59381d72 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -183,6 +183,7 @@ export interface Config { validate?: FormValidator; validateOnChange?: boolean; validateOnBlur?: boolean; + ignoreFields?: string[]; onReset?: OnReset; onSubmit?: OnSubmit; onError?: OnError; diff --git a/src/types/react-cool-form.d.ts b/src/types/react-cool-form.d.ts index f6966098..f55d25cf 100644 --- a/src/types/react-cool-form.d.ts +++ b/src/types/react-cool-form.d.ts @@ -154,6 +154,7 @@ declare module "react-cool-form" { validate?: FormValidator; validateOnChange?: boolean; validateOnBlur?: boolean; + ignoreFields?: string[]; onReset?: OnReset; onSubmit?: OnSubmit; onError?: OnError; diff --git a/src/useFormState.ts b/src/useFormState.ts index eec1ab4a..2790cdad 100644 --- a/src/useFormState.ts +++ b/src/useFormState.ts @@ -10,7 +10,7 @@ import { UsedRef, } from "./types"; import useLatest from "./useLatest"; -import { get, set, isEmptyObject } from "./utils"; +import { get, isEmptyObject, set } from "./utils"; export default ( initialValues: V, diff --git a/src/utils.ts b/src/utils.ts index 7f39a305..4b9f95b4 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -6,6 +6,12 @@ export const warn = (...args: any[]): void => { if (__DEV__) console.warn(...args); }; +export const arrayToObject = (arr: any[]): Record => + arr.reduce((obj, key) => { + obj[key] = true; + return obj; + }, {}); + export const isNumberField = (field: FieldElement): field is HTMLInputElement => field.type === "number";