import { Box, Stack, useTheme } from '@mui/material'; import SettingsIcon from '@mui/icons-material/Settings'; import Typography from '@mui/material/Typography'; import React, { ReactNode, RefObject, useContext, useEffect } from 'react'; import { Formik, FormikProps, FormikValues, useFormikContext } from 'formik'; import ToolOptionGroups, { ToolOptionGroup } from './ToolOptionGroups'; import { CustomSnackBarContext } from '../../contexts/CustomSnackBarContext'; type UpdateField = (field: Y, value: T[Y]) => void; const FormikListenerComponent = ({ initialValues, input, compute }: { initialValues: T; input: any; compute: (optionsValues: T, input: any) => void; }) => { const { values } = useFormikContext(); const { showSnackBar } = useContext(CustomSnackBarContext); useEffect(() => { try { compute(values, input); } catch (exception: unknown) { if (exception instanceof Error) showSnackBar(exception.message, 'error'); } }, [values, input]); return null; // This component doesn't render anything }; interface FormikHelperProps { compute: (optionsValues: T, input: any) => void; input: any; children?: ReactNode; getGroups: ( formikProps: FormikProps & { updateField: UpdateField } ) => ToolOptionGroup[]; formikProps: FormikProps; } const ToolBody = ({ compute, input, children, getGroups, formikProps }: FormikHelperProps) => { const { values, setFieldValue } = useFormikContext(); const updateField: UpdateField = (field, value) => { // @ts-ignore setFieldValue(field, value); }; return ( compute={compute} input={input} initialValues={values} /> {children} ); }; export default function ToolOptions({ children, initialValues, validationSchema, compute, input, getGroups, formRef }: { children?: ReactNode; initialValues: T; validationSchema: any | (() => any); compute: (optionsValues: T, input: any) => void; input?: any; getGroups: ( formikProps: FormikProps & { updateField: UpdateField } ) => ToolOptionGroup[]; formRef?: RefObject>; }) { const theme = useTheme(); return ( Tool options {}} > {(formikProps) => ( {children} )} ); }