{"version":3,"file":"use-form-status.mjs","names":[],"sources":["../../../src/hooks/use-form-status/use-form-status.ts"],"sourcesContent":["import { useCallback, useRef, useState } from 'react';\nimport isEqual from 'fast-deep-equal';\nimport { getStatus } from '../../get-status';\nimport { clearListState } from '../../lists';\nimport { getPath } from '../../paths';\nimport {\n  ClearFieldDirty,\n  FormMode,\n  FormStatus,\n  GetFieldStatus,\n  ResetDirty,\n  ResetStatus,\n  SetCalculatedFieldDirty,\n  SetFieldDirty,\n  SetFieldTouched,\n} from '../../types';\nimport type { $FormValues } from '../use-form-values/use-form-values';\n\nexport interface $FormStatus<out Values extends Record<string, any>> {\n  touchedState: FormStatus;\n  dirtyState: FormStatus;\n  touchedRef: React.RefObject<FormStatus>;\n  dirtyRef: React.RefObject<FormStatus>;\n  setTouched: React.Dispatch<React.SetStateAction<FormStatus>>;\n  setDirty: React.Dispatch<React.SetStateAction<FormStatus>>;\n  resetDirty: ResetStatus;\n  resetTouched: ResetStatus;\n  isTouched: GetFieldStatus<Values>;\n  setFieldTouched: SetFieldTouched<Values>;\n  setFieldDirty: SetFieldDirty<Values>;\n  setTouchedState: React.Dispatch<React.SetStateAction<FormStatus>>;\n  setDirtyState: React.Dispatch<React.SetStateAction<FormStatus>>;\n  clearFieldDirty: ClearFieldDirty;\n  isDirty: GetFieldStatus<Values>;\n  getDirty: () => FormStatus;\n  getTouched: () => FormStatus;\n  setCalculatedFieldDirty: SetCalculatedFieldDirty<Values>;\n}\n\ninterface UseFormStatusInput<out Values extends Record<string, any>> {\n  initialDirty: FormStatus;\n  initialTouched: FormStatus;\n  mode: FormMode;\n  $values: $FormValues<Values>;\n}\n\nexport function useFormStatus<Values extends Record<string, any>>({\n  initialDirty,\n  initialTouched,\n  mode,\n  $values,\n}: UseFormStatusInput<Values>): $FormStatus<Values> {\n  const [touchedState, setTouchedState] = useState(initialTouched);\n  const [dirtyState, setDirtyState] = useState(initialDirty);\n\n  const touchedRef = useRef(initialTouched);\n  const dirtyRef = useRef(initialDirty);\n\n  const setTouched = useCallback((values: FormStatus | ((current: FormStatus) => FormStatus)) => {\n    const resolvedValues = typeof values === 'function' ? values(touchedRef.current) : values;\n    touchedRef.current = resolvedValues;\n\n    if (mode === 'controlled') {\n      setTouchedState(resolvedValues);\n    }\n  }, []);\n\n  const setDirty = useCallback(\n    (values: FormStatus | ((current: FormStatus) => FormStatus), forceUpdate = false) => {\n      const resolvedValues = typeof values === 'function' ? values(dirtyRef.current) : values;\n      dirtyRef.current = resolvedValues;\n\n      if (mode === 'controlled' || forceUpdate) {\n        setDirtyState(resolvedValues);\n      }\n    },\n    []\n  );\n\n  const resetTouched: ResetStatus = useCallback(() => setTouched({}), []);\n\n  const resetDirty: ResetDirty<Values> = useCallback((values) => {\n    const newSnapshot = values\n      ? { ...$values.refValues.current, ...values }\n      : $values.refValues.current;\n    $values.setValuesSnapshot(newSnapshot);\n    setDirty({});\n  }, []);\n\n  const setFieldTouched: SetFieldTouched<Values> = useCallback((path, touched) => {\n    setTouched((currentTouched) => {\n      if (getStatus(currentTouched, path) === touched) {\n        return currentTouched;\n      }\n\n      return { ...currentTouched, [path]: touched };\n    });\n  }, []);\n\n  const setFieldDirty: SetFieldDirty<Values> = useCallback((path, dirty, forceUpdate) => {\n    setDirty((currentDirty) => {\n      if (getStatus(currentDirty, path) === dirty) {\n        return currentDirty;\n      }\n\n      return { ...currentDirty, [path]: dirty };\n    }, forceUpdate);\n  }, []);\n\n  const setCalculatedFieldDirty: SetCalculatedFieldDirty<Values> = useCallback((path, value) => {\n    const currentDirty = getStatus(dirtyRef.current, path);\n    const dirty = !isEqual(getPath(path, $values.getValuesSnapshot()), value);\n    const clearedState = clearListState(path, dirtyRef.current);\n    clearedState[path as string] = dirty;\n    setDirty(clearedState, currentDirty !== dirty);\n  }, []);\n\n  const isTouched: GetFieldStatus<Values> = useCallback(\n    (path) => getStatus(touchedRef.current, path),\n    []\n  );\n\n  const clearFieldDirty: ClearFieldDirty = useCallback(\n    (path) =>\n      setDirty((current) => {\n        if (typeof path !== 'string') {\n          return current;\n        }\n\n        const result = clearListState(path, current);\n        delete result[path];\n\n        if (isEqual(result, current)) {\n          return current;\n        }\n\n        return result;\n      }),\n    []\n  );\n\n  const isDirty: GetFieldStatus<Values> = useCallback((path) => {\n    if (path) {\n      const overriddenValue = getPath(path, dirtyRef.current);\n      if (typeof overriddenValue === 'boolean') {\n        return overriddenValue;\n      }\n\n      const sliceOfValues = getPath(path, $values.refValues.current);\n      const sliceOfInitialValues = getPath(path, $values.valuesSnapshot.current);\n      return !isEqual(sliceOfValues, sliceOfInitialValues);\n    }\n\n    const isOverridden = Object.keys(dirtyRef.current).length > 0;\n    if (isOverridden) {\n      return getStatus(dirtyRef.current);\n    }\n\n    return !isEqual($values.refValues.current, $values.valuesSnapshot.current);\n  }, []);\n\n  const getDirty = useCallback(() => dirtyRef.current, []);\n  const getTouched = useCallback(() => touchedRef.current, []);\n\n  return {\n    touchedState,\n    dirtyState,\n    touchedRef,\n    dirtyRef,\n    setTouched,\n    setDirty,\n    resetDirty,\n    resetTouched,\n    isTouched,\n    setFieldTouched,\n    setFieldDirty,\n    setTouchedState,\n    setDirtyState,\n    clearFieldDirty,\n    isDirty,\n    getDirty,\n    getTouched,\n    setCalculatedFieldDirty,\n  };\n}\n"],"mappings":"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"}