import * as React from 'react'; import { useContext, useEffect, useState, } from 'react'; import { FormizStepProps, StepState } from './types/step.types'; import { ErrorStepWithoutName, ErrorStepWithoutForm } from './errors'; import { useFormContext, defaultFormState } from './Formiz'; import { useRefValue } from './utils'; export const StepContext = React.createContext({}); export const useStepContext = (): any => useContext(StepContext); export const FormizStep: React.FC = ({ as: Tag = 'div', children, name, label, order, isEnabled = true, style = {}, autoHide = true, ...rest }: FormizStepProps) => { if (!name) { throw ErrorStepWithoutName; } const { formStateRef, actions, subjects, } = useFormContext(); if (!subjects || !actions) { throw ErrorStepWithoutForm; } const [formState, setFormState] = useState(formStateRef?.current ?? defaultFormState); const [state, setState] = useState>({ name, label, isVisited: false, order: order ?? 0, }); const isActive = formStateRef?.current?.navigatedStepName ? formStateRef?.current?.navigatedStepName === name : formStateRef?.current?.initialStepName === name; const actionsRef = useRefValue(actions); const subjectsRef = useRefValue(subjects); // Subscribe to form state for rerender useEffect(() => { const subscription = subjectsRef.current.onFormUpdate .subscription .subscribe(setFormState); return () => subscription.unsubscribe(); }, [subjectsRef]); useEffect(() => { if (isActive && !state.isVisited) { setState((prevState) => ({ ...prevState, isVisited: true })); } }, [isActive, state.isVisited]); // Register / Update the step useEffect(() => { actionsRef.current.updateStep({ ...state, isEnabled, }); }, [actionsRef, state, isEnabled]); // Unregister the step useEffect(() => () => { actionsRef.current.unregisterStep(name); }, [actionsRef, name]); if (!isEnabled) { return null; } return ( {isEnabled && children} ); };