import { ContextScope } from "@reins/utils"; import { ObjectType, PathsOf, ObjectPathToValue } from "@reins/types"; import { Form as FormComponent, FormProps, FormButton, FormButtonProps, FormPage, FormPageProps, FormController, FormControllerProps, } from "components"; import { createUseField, UseField, UseFieldOptions } from "hooks"; import { FormAdapter, FormAdapterOptionsType } from "utils"; import { useActions } from "hooks/use-actions/use-actions"; import { useFormState } from "hooks/use-form-state/use-form-state"; export function createForm(initialValues: Values, options?: FormAdapterOptionsType) { const form = new FormAdapter>(initialValues, options); /* ----------------------------------------------------------------------------------------------- * Context * ---------------------------------------------------------------------------------------------*/ const formContexts = new ContextScope("Form").createContext("FormProvider", { form }); const [FormProvider, useProviderContext] = formContexts.getContext("FormProvider"); const Provider = (props: Omit[0], "__context">) => ( ); /* ----------------------------------------------------------------------------------------------- * Form Hooks * ---------------------------------------------------------------------------------------------*/ const useFormContext = (componentName: string) => { return useProviderContext(componentName, formContexts); }; const useField = >( name: N, args?: UseFieldOptions>, ObjectPathToValue>, ) => { return createUseField(useFormContext)>, ObjectPathToValue>( name, args, ); }; const useState = (...args: Parameters<(typeof form)["store"]["useStore"]>) => { return useFormState(form, ...args); }; const useFormActions = () => { return useActions(form); }; /* ----------------------------------------------------------------------------------------------- * Form Components * ---------------------------------------------------------------------------------------------*/ const Form = (props: FormProps) => ; const Button = (props: FormButtonProps) => ; const Page = (props: FormPageProps) => ; const Controller = , Value extends ObjectPathToValue>( props: FormControllerProps>, Name, Value>, ) => ( >, Name, Value> {...props} // eslint-disable-next-line @typescript-eslint/no-explicit-any useField={useField as UseField, any>} /> ); return { form, useActions: useFormActions, useFormState: useState, Form, FormButton: Button, FormPage: Page, FormController: Controller, useFormContext, useField, }; }