import { Box, Stack, useTheme } from '@mui/material'; import SettingsIcon from '@mui/icons-material/Settings'; import Typography from '@mui/material/Typography'; import React, { ReactNode, useContext } from 'react'; import { FormikProps, FormikValues, useFormikContext } from 'formik'; import ToolOptionGroups, { ToolOptionGroup } from './ToolOptionGroups'; import { CustomSnackBarContext } from '../../contexts/CustomSnackBarContext'; export type UpdateField = (field: Y, value: T[Y]) => void; const FormikListenerComponent = ({ input, compute }: { input: any; compute: (optionsValues: T, input: any) => void; }) => { const { values } = useFormikContext(); const { showSnackBar } = useContext(CustomSnackBarContext); React.useEffect(() => { try { compute(values, input); } catch (exception: unknown) { if (exception instanceof Error) showSnackBar(exception.message, 'error'); else console.error(exception); } }, [values, input, showSnackBar]); return null; // This component doesn't render anything }; export type GetGroupsType = ( formikProps: FormikProps & { updateField: UpdateField } ) => ToolOptionGroup[]; export default function ToolOptions({ children, compute, input, getGroups }: { children?: ReactNode; compute: (optionsValues: T, input: any) => void; input?: any; getGroups: GetGroupsType | null; }) { const theme = useTheme(); const formikContext = useFormikContext(); // Early return if no groups to display if (!getGroups) { return null; } const updateField: UpdateField = (field, value) => { formikContext.setFieldValue(field as string, value); }; return ( Tool options compute={compute} input={input} /> {children} ); }