import React, { createContext, useCallback, useContext, useState, type ReactNode } from 'react'; import type { FormField } from '@openmrs/esm-form-engine-lib'; import type { Concept } from '@types'; interface FormFieldContextType { formField: FormField; setFormField: (value: FormField | ((prev: FormField) => FormField)) => void; concept: Concept; setConcept: React.Dispatch>; isConceptValid?: boolean; setIsConceptValid?: React.Dispatch>; updateParentFormField?: (updatedFormField: FormField) => void; isObsGrouped?: boolean; } const FormFieldContext = createContext(undefined); export const FormFieldProvider: React.FC<{ children: ReactNode; initialFormField: FormField; isObsGrouped?: boolean; selectedConcept?: Concept; updateParentFormField?: (updatedFormField: FormField) => void; }> = ({ children, initialFormField, isObsGrouped = false, selectedConcept = null, updateParentFormField }) => { const [formField, setFormFieldInternal] = useState(initialFormField); const [concept, setConcept] = useState(selectedConcept); const [isConceptValid, setIsConceptValid] = useState(true); const setFormField = useCallback( (valueOrUpdater: FormField | ((prev: FormField) => FormField)) => { if (isObsGrouped) { const newValue = typeof valueOrUpdater === 'function' ? valueOrUpdater(formField) : valueOrUpdater; setFormFieldInternal(newValue); updateParentFormField?.(newValue); } else { setFormFieldInternal(valueOrUpdater); } }, [isObsGrouped, updateParentFormField, formField], ); return ( {children} ); }; export const useFormField = (): FormFieldContextType => { const context = useContext(FormFieldContext); if (!context) { throw new Error('useFormField must be used within a FormFieldProvider'); } return context; };