import type { FormState, FormOptions } from '@tanstack/form-core' import { FormApi, functionalUpdate } from '@tanstack/form-core' import type { NoInfer } from '@tanstack/react-store' import { useStore } from '@tanstack/react-store' import React from 'react' import { type UseField, type FieldComponent, Field, useField } from './useField' import { formContext } from './formContext' export type FormSubmitEvent = React.FormEvent declare module '@tanstack/form-core' { interface Register { FormSubmitEvent: FormSubmitEvent } // eslint-disable-next-line no-shadow interface FormApi { Provider: (props: { children: any }) => any getFormProps: () => FormProps Field: FieldComponent useField: UseField useStore: >>( selector?: (state: NoInfer>) => TSelected, ) => TSelected Subscribe: >>(props: { selector?: (state: NoInfer>) => TSelected children: | ((state: NoInfer) => React.ReactNode) | React.ReactNode }) => any } } export type FormProps = { onSubmit: (e: FormSubmitEvent) => void disabled: boolean } export function useForm(opts?: FormOptions): FormApi { const [formApi] = React.useState(() => { // @ts-ignore const api = new FormApi(opts) api.Provider = (props) => ( ) api.getFormProps = () => { return { onSubmit: formApi.handleSubmit, disabled: api.state.isSubmitting, } } api.Field = Field as any api.useField = useField as any api.useStore = ( // @ts-ignore selector, ) => { // eslint-disable-next-line react-hooks/rules-of-hooks return useStore(api.store as any, selector as any) as any } api.Subscribe = ( // @ts-ignore props, ) => { return functionalUpdate( props.children, // eslint-disable-next-line react-hooks/rules-of-hooks useStore(api.store as any, props.selector as any), ) as any } return api }) formApi.useStore((state) => state.isSubmitting) formApi.update(opts) return formApi as any }