fix: remove form.Form for headless form.getFormProps()

This commit is contained in:
Tanner Linsley
2023-05-04 15:39:15 -07:00
parent 357235342e
commit b37628d337
5 changed files with 20 additions and 49 deletions

View File

@@ -8,9 +8,9 @@ title: Form API
When using `@tanstack/react-form`, the [core form API](../../reference/formApi) is extended with additional methods for React-specific functionality: When using `@tanstack/react-form`, the [core form API](../../reference/formApi) is extended with additional methods for React-specific functionality:
- ```tsx - ```tsx
Form: FormComponent getFormProps: () => FormProps
``` ```
- A pre-bound and type-safe form component, specific to this forms instance. - A function that returns props for the form element.
- ```tsx - ```tsx
Field: FieldComponent<TFormData> Field: FieldComponent<TFormData>
``` ```

View File

@@ -32,14 +32,3 @@ A type representing a form component.
- `(props: FormProps) => any` - `(props: FormProps) => any`
- A function that takes `FormProps` as an argument and returns a form component. - A function that takes `FormProps` as an argument and returns a form component.
### `createFormComponent`
```tsx
export function createFormComponent(formApi: FormApi<any>): FormComponent
```
A function that creates a form component with the provided form API instance.
- `formApi`
- An instance of the `FormApi<any>` class.

View File

@@ -45,7 +45,7 @@ export default function App() {
<div> <div>
<h1>Simple Form Example</h1> <h1>Simple Form Example</h1>
{/* A pre-bound form component */} {/* A pre-bound form component */}
<form.Form> <form {...form.getFormProps()}>
<div> <div>
{/* A type-safe and pre-bound field component*/} {/* A type-safe and pre-bound field component*/}
<form.Field <form.Field

View File

@@ -22,7 +22,7 @@ export type {
export { FormApi, FieldApi, functionalUpdate } from '@tanstack/form-core' export { FormApi, FieldApi, functionalUpdate } from '@tanstack/form-core'
export type { FormComponent, FormProps } from './useForm' export type { FormProps } from './useForm'
export { useForm } from './useForm' export { useForm } from './useForm'
export type { UseField, FieldComponent } from './useField' export type { UseField, FieldComponent } from './useField'

View File

@@ -6,14 +6,16 @@ import React from 'react'
import { type UseField, type FieldComponent, Field, useField } from './useField' import { type UseField, type FieldComponent, Field, useField } from './useField'
import { formContext } from './formContext' import { formContext } from './formContext'
export type FormSubmitEvent = React.FormEvent<HTMLFormElement>
declare module '@tanstack/form-core' { declare module '@tanstack/form-core' {
interface Register { interface Register {
FormSubmitEvent: React.FormEvent<HTMLFormElement> FormSubmitEvent: FormSubmitEvent
} }
// eslint-disable-next-line no-shadow // eslint-disable-next-line no-shadow
interface FormApi<TFormData> { interface FormApi<TFormData> {
Form: FormComponent getFormProps: () => FormProps
Field: FieldComponent<TFormData, TFormData> Field: FieldComponent<TFormData, TFormData>
useField: UseField<TFormData> useField: UseField<TFormData>
useStore: <TSelected = NoInfer<FormState<TFormData>>>( useStore: <TSelected = NoInfer<FormState<TFormData>>>(
@@ -28,12 +30,22 @@ declare module '@tanstack/form-core' {
} }
} }
export type FormProps = {
onSubmit: (e: FormSubmitEvent) => void
disabled: boolean
}
export function useForm<TData>(opts?: FormOptions<TData>): FormApi<TData> { export function useForm<TData>(opts?: FormOptions<TData>): FormApi<TData> {
const [formApi] = React.useState(() => { const [formApi] = React.useState(() => {
// @ts-ignore // @ts-ignore
const api = new FormApi<TData>(opts) const api = new FormApi<TData>(opts)
api.Form = createFormComponent(api) api.getFormProps = () => {
return {
onSubmit: formApi.handleSubmit,
disabled: api.state.isSubmitting,
}
}
api.Field = Field as any api.Field = Field as any
api.useField = useField as any api.useField = useField as any
api.useStore = ( api.useStore = (
@@ -57,38 +69,8 @@ export function useForm<TData>(opts?: FormOptions<TData>): FormApi<TData> {
return api return api
}) })
formApi.useStore((state) => state.isSubmitting)
formApi.update(opts) formApi.update(opts)
return formApi as any return formApi as any
} }
export type FormProps = React.HTMLProps<HTMLFormElement> & {
children: React.ReactNode
noFormElement?: boolean
}
export type FormComponent = (props: FormProps) => any
function createFormComponent(formApi: FormApi<any>) {
const Form: FormComponent = ({ children, noFormElement, ...rest }) => {
const isSubmitting = formApi.useStore((state) => state.isSubmitting)
return (
<formContext.Provider value={{ formApi }}>
{noFormElement ? (
children
) : (
<form
onSubmit={formApi.handleSubmit}
disabled={isSubmitting}
{...rest}
>
{children}
</form>
)}
</formContext.Provider>
)
}
return Form
}