File tree Expand file tree Collapse file tree 7 files changed +103
-51
lines changed
framework/react/reference
examples/react/simple/src Expand file tree Collapse file tree 7 files changed +103
-51
lines changed Original file line number Diff line number Diff line change 1+ ---
2+ id : createFormFactory
3+ title : createFormFactory
4+ ---
5+
6+ ### ` createFormFactory `
7+
8+ ``` tsx
9+ export function createFormFactory<TFormData >(
10+ opts ? : FormOptions <TFormData >,
11+ ): FormFactory <TFormData >
12+ ```
13+
14+ A function that creates a new `FormFactory<TFormData >` instance.
15+
16+ - ` opts `
17+ - Optional form options and a ` listen ` function to be called with the form state.
18+
19+ ### ` FormFactory<TFormData> `
20+
21+ A type representing a form factory. Form factories provide a type-safe way to interact with the form API as opposed to using the globally exported form utilities.
22+
23+ ` ` ` tsx
24+ export type FormFactory<TFormData> = {
25+ useForm: (opts?: FormOptions<TFormData>) => FormApi<TFormData>
26+ useField: UseField<TFormData>
27+ Field: FieldComponent<TFormData>
28+ }
29+ ` ` `
30+
31+ - ` useForm `
32+ - A custom hook that creates and returns a new instance of the ` FormApi<TFormData> ` class .
33+ - ` useField `
34+ - A custom hook that returns an instance of the ` FieldApi<TFormData> ` class .
35+ - ` Field `
36+ - A form field component .
Original file line number Diff line number Diff line change @@ -35,10 +35,6 @@ An object representing the options for a form.
3535 validate ?: (values : TData , formApi : FormApi <TData >) => Promise < any >
3636 ```
3737 - A function for custom validation logic for the form.
38- - ``` tsx
39- debugForm ?: boolean
40- ```
41- - A boolean flag to enable or disable form debugging.
4238- ``` tsx
4339 defaultValidatePristine ?: boolean
4440 ```
Original file line number Diff line number Diff line change @@ -2,10 +2,22 @@ import React from "react";
22import ReactDOM from "react-dom/client" ;
33import { FieldApi , createFormFactory } from "@tanstack/react-form" ;
44
5- const formFactory = createFormFactory ( {
5+ type Person = {
6+ firstName : string ;
7+ lastName : string ;
8+ hobbies : Hobby [ ] ;
9+ } ;
10+
11+ type Hobby = {
12+ name : string ;
13+ description : string ;
14+ } ;
15+
16+ const formFactory = createFormFactory < Person > ( {
617 defaultValues : {
718 firstName : "" ,
819 lastName : "" ,
20+ hobbies : [ ] ,
921 } ,
1022} ) ;
1123
@@ -68,6 +80,18 @@ export default function App() {
6880 ) }
6981 />
7082 </ div >
83+ < div >
84+ < form . Field
85+ name = "hobbies"
86+ children = { ( field ) => (
87+ < >
88+ < label htmlFor = { field . name } > Last Name:</ label >
89+ < input name = { field . name } { ...field . getInputProps ( ) } />
90+ < FieldInfo field = { field } />
91+ </ >
92+ ) }
93+ />
94+ </ div >
7195 < form . Subscribe
7296 selector = { ( state ) => [ state . canSubmit , state . isSubmitting ] }
7397 children = { ( [ canSubmit , isSubmitting ] ) => (
Original file line number Diff line number Diff line change 1- import type { FormEvent } from 'react'
21import { Store } from '@tanstack/store'
32//
43import type { DeepKeys , DeepValue , Updater } from './utils'
@@ -11,7 +10,6 @@ export type FormOptions<TData> = {
1110 onSubmit ?: ( values : TData , formApi : FormApi < TData > ) => void
1211 onInvalidSubmit ?: ( values : TData , formApi : FormApi < TData > ) => void
1312 validate ?: ( values : TData , formApi : FormApi < TData > ) => Promise < any >
14- debugForm ?: boolean
1513 defaultValidatePristine ?: boolean
1614 defaultValidateOn ?: ValidationCause
1715 defaultValidateAsyncOn ?: ValidationCause
@@ -53,7 +51,7 @@ export type FormState<TData> = {
5351 submissionAttempts : number
5452}
5553
56- export function getDefaultFormState < TData > (
54+ function getDefaultFormState < TData > (
5755 defaultState : Partial < FormState < TData > > ,
5856) : FormState < TData > {
5957 return {
@@ -247,7 +245,7 @@ export class FormApi<TFormData> {
247245 return this . validationMeta . validationPromise
248246 }
249247
250- handleSubmit = async ( e : FormEvent & { __handled ?: boolean } ) => {
248+ handleSubmit = async ( e : Event ) => {
251249 e . preventDefault ( )
252250 e . stopPropagation ( )
253251
Original file line number Diff line number Diff line change 11import type { FormApi , FormOptions } from '@tanstack/form-core'
22import { createUseField , type UseField } from './useField'
33import { useForm } from './useForm'
4+ import { createFieldComponent , type FieldComponent } from './Field'
45
56export type FormFactory < TFormData > = {
67 useForm : ( opts ?: FormOptions < TFormData > ) => FormApi < TFormData >
78 useField : UseField < TFormData >
9+ Field : FieldComponent < TFormData >
810}
911
1012export function createFormFactory < TFormData > (
@@ -14,6 +16,7 @@ export function createFormFactory<TFormData>(
1416 useForm : ( opts ) => {
1517 return useForm < TFormData > ( { ...defaultOpts , ...opts } as any ) as any
1618 } ,
17- useField : createUseField ( ) ,
19+ useField : createUseField < TFormData > ( ) ,
20+ Field : createFieldComponent < TFormData > ( ) ,
1821 }
1922}
Original file line number Diff line number Diff line change 1- export * from '@tanstack/form-core'
2- export * from './useForm'
3- export * from './Field'
4- export * from './useField'
5- export * from './createFormFactory'
1+ export type {
2+ ChangeProps ,
3+ DeepKeys ,
4+ DeepValue ,
5+ FieldApiOptions ,
6+ FieldInfo ,
7+ FieldMeta ,
8+ FieldOptions ,
9+ FieldState ,
10+ FormOptions ,
11+ FormState ,
12+ InputProps ,
13+ RequiredByKey ,
14+ Updater ,
15+ UpdaterFn ,
16+ UserChangeProps ,
17+ UserInputProps ,
18+ ValidationCause ,
19+ ValidationError ,
20+ ValidationMeta ,
21+ } from '@tanstack/form-core'
22+
23+ export { FormApi , FieldApi , functionalUpdate } from '@tanstack/form-core'
24+
25+ export type { FormComponent , FormProps } from './useForm'
26+ export { useForm } from './useForm'
27+
28+ export type { FieldComponent } from './Field'
29+ export { Field } from './Field'
30+
31+ export type { UseField } from './useField'
32+ export { useField } from './useField'
33+
34+ export type { FormFactory } from './createFormFactory'
35+ export { createFormFactory } from './createFormFactory'
Original file line number Diff line number Diff line change @@ -54,8 +54,6 @@ export function useForm<TData>(opts?: FormOptions<TData>): FormApi<TData> {
5454 return api
5555 } )
5656
57- // React.useEffect(() => formApi.mount(), [])
58-
5957 return formApi as any
6058}
6159
@@ -66,7 +64,7 @@ export type FormProps = React.HTMLProps<HTMLFormElement> & {
6664
6765export type FormComponent = ( props : FormProps ) => any
6866
69- export function createFormComponent ( formApi : FormApi < any > ) {
67+ function createFormComponent ( formApi : FormApi < any > ) {
7068 const Form : FormComponent = ( { children, noFormElement, ...rest } ) => {
7169 const isSubmitting = formApi . useStore ( ( state ) => state . isSubmitting )
7270
@@ -80,26 +78,6 @@ export function createFormComponent(formApi: FormApi<any>) {
8078 disabled = { isSubmitting }
8179 { ...rest }
8280 >
83- { formApi . options . debugForm ? (
84- < div
85- style = { {
86- margin : '2rem 0' ,
87- } }
88- >
89- < div
90- style = { {
91- fontWeight : 'bolder' ,
92- } }
93- >
94- Form State
95- </ div >
96- < pre >
97- < code >
98- { JSON . stringify ( formApi , safeStringifyReplace ( ) , 2 ) }
99- </ code >
100- </ pre >
101- </ div >
102- ) : null }
10381 { children }
10482 </ form >
10583 ) }
@@ -109,16 +87,3 @@ export function createFormComponent(formApi: FormApi<any>) {
10987
11088 return Form
11189}
112-
113- function safeStringifyReplace ( ) {
114- const set = new Set ( )
115- return ( _key : string , value : any ) => {
116- if ( typeof value === 'object' || Array . isArray ( value ) ) {
117- if ( set . has ( value ) ) {
118- return '(circular value)'
119- }
120- set . add ( value )
121- }
122- return typeof value === 'function' ? undefined : value
123- }
124- }
You can’t perform that action at this time.
0 commit comments