import React, {createContext, useContext, useMemo, useRef} from 'react'; interface FormProps { onSubmit: () => void; children: React.ReactNode; } interface FormManager { registerValidator: (v: () => boolean) => void; deregisterValidator: (v: () => boolean) => void; submit: () => void; } const FormContext = createContext(null); export const useFormContext = () => useContext(FormContext); export function Form(props: FormProps) { const {children, onSubmit} = props; const validators = useRef<(() => boolean)[]>([]); const v = useMemo( () => ({registerValidator, deregisterValidator, submit}), [registerValidator, deregisterValidator, submit] ); function registerValidator(validator: () => boolean) { validators.current.push(validator); }; function deregisterValidator(validator: () => boolean) { validators.current = validators.current.filter((v) => v !== validator); }; function submit() { const valid = validators.current.map((v) => v()).reduce((p, v) => p && v); if (valid) onSubmit(); } return {children}; }