Skip to content

Commit 2a31bd8

Browse files
committed
feat: remove getFormProps to support React Native
1 parent 0d7e545 commit 2a31bd8

File tree

7 files changed

+38
-64
lines changed

7 files changed

+38
-64
lines changed

docs/framework/react/reference/formApi.md

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,6 @@ title: Form API
77

88
When using `@tanstack/react-form`, the [core form API](../../reference/formApi) is extended with additional methods for React-specific functionality:
99

10-
- ```tsx
11-
getFormProps: () => FormProps
12-
```
13-
- A function that returns props for the form element.
1410
- ```tsx
1511
Field: FieldComponent<TFormData>
1612
```

docs/overview.md

Lines changed: 28 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -26,61 +26,67 @@ In the example below, you can see TanStack Form in action with the React framewo
2626
[Open in CodeSandbox](https://codesandbox.io/s/github/tannerlinsley/react-form/tree/main/examples/react/simple)
2727

2828
```tsx
29-
import React from "react";
30-
import ReactDOM from "react-dom/client";
31-
import { useForm } from "@tanstack/react-form";
32-
import type { FieldApi } from "@tanstack/react-form";
29+
import React from 'react'
30+
import ReactDOM from 'react-dom/client'
31+
import { useForm } from '@tanstack/react-form'
32+
import type { FieldApi } from '@tanstack/react-form'
3333

3434
function FieldInfo({ field }: { field: FieldApi<any, any> }) {
3535
return (
3636
<>
3737
{field.state.meta.touchedError ? (
3838
<em>{field.state.meta.touchedError}</em>
39-
) : null}{" "}
40-
{field.state.meta.isValidating ? "Validating..." : null}
39+
) : null}{' '}
40+
{field.state.meta.isValidating ? 'Validating...' : null}
4141
</>
42-
);
42+
)
4343
}
4444

4545
export default function App() {
4646
const form = useForm({
4747
// Memoize your default values to prevent re-renders
4848
defaultValues: React.useMemo(
4949
() => ({
50-
firstName: "",
51-
lastName: "",
50+
firstName: '',
51+
lastName: '',
5252
}),
5353
[],
5454
),
5555
onSubmit: async (values) => {
5656
// Do something with form data
57-
console.log(values);
57+
console.log(values)
5858
},
59-
});
59+
})
6060

6161
return (
6262
<div>
6363
<h1>Simple Form Example</h1>
6464
{/* A pre-bound form component */}
6565
<form.Provider>
66-
<form {...form.getFormProps()}>
66+
<form
67+
onSubmit={(e) => {
68+
e.preventDefault()
69+
e.stopPropagation()
70+
void form.handleSubmit()
71+
}}
72+
>
6773
<div>
6874
{/* A type-safe and pre-bound field component*/}
6975
<form.Field
7076
name="firstName"
7177
onChange={(value) =>
7278
!value
73-
? "A first name is required"
79+
? 'A first name is required'
7480
: value.length < 3
75-
? "First name must be at least 3 characters"
81+
? 'First name must be at least 3 characters'
7682
: undefined
7783
}
7884
onChangeAsyncDebounceMs={500}
7985
onChangeAsync={async (value) => {
80-
await new Promise((resolve) => setTimeout(resolve, 1000));
86+
await new Promise((resolve) => setTimeout(resolve, 1000))
8187
return (
82-
value.includes("error") && 'No "error" allowed in first name'
83-
);
88+
value.includes('error') && 'No "error" allowed in first name'
89+
)
8490
}}
8591
children={(field) => {
8692
// Avoid hasty abstractions. Render props are great!
@@ -90,7 +96,7 @@ export default function App() {
9096
<input name={field.name} {...field.getInputProps()} />
9197
<FieldInfo field={field} />
9298
</>
93-
);
99+
)
94100
}}
95101
/>
96102
</div>
@@ -110,19 +116,19 @@ export default function App() {
110116
selector={(state) => [state.canSubmit, state.isSubmitting]}
111117
children={([canSubmit, isSubmitting]) => (
112118
<button type="submit" disabled={!canSubmit}>
113-
{isSubmitting ? "..." : "Submit"}
119+
{isSubmitting ? '...' : 'Submit'}
114120
</button>
115121
)}
116122
/>
117123
</form>
118124
</form.Provider>
119125
</div>
120-
);
126+
)
121127
}
122128

123-
const rootElement = document.getElementById("root")!;
129+
const rootElement = document.getElementById('root')!
124130

125-
ReactDOM.createRoot(rootElement).render(<App />);
131+
ReactDOM.createRoot(rootElement).render(<App />)
126132
```
127133

128134
## You talked me into it, so what now?

examples/react/simple/src/index.tsx

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,13 @@ export default function App() {
3535
<h1>Simple Form Example</h1>
3636
{/* A pre-bound form component */}
3737
<form.Provider>
38-
<form {...form.getFormProps()}>
38+
<form
39+
onSubmit={(e) => {
40+
e.preventDefault();
41+
e.stopPropagation();
42+
void form.handleSubmit();
43+
}}
44+
>
3945
<div>
4046
{/* A type-safe and pre-bound field component*/}
4147
<form.Field

packages/form-core/src/FormApi.ts

Lines changed: 2 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,6 @@ import type { DeepKeys, DeepValue, Updater } from './utils'
44
import { functionalUpdate, getBy, setBy } from './utils'
55
import type { FieldApi, FieldMeta, ValidationCause } from './FieldApi'
66

7-
export interface Register {
8-
// FormSubmitEvent
9-
}
10-
11-
export type FormSubmitEvent = Register extends {
12-
FormSubmitEvent: infer E
13-
}
14-
? E
15-
: Event
16-
177
export type FormOptions<TData> = {
188
defaultValues?: TData
199
defaultState?: Partial<FormState<TData>>
@@ -223,20 +213,15 @@ export class FormApi<TFormData> {
223213
return Promise.all(fieldValidationPromises)
224214
}
225215

226-
// validateForm = async () => {}
227-
228-
handleSubmit = async (e: FormSubmitEvent) => {
229-
e.preventDefault()
230-
e.stopPropagation()
231-
216+
handleSubmit = async () => {
232217
// Check to see that the form and all fields have been touched
233218
// If they have not, touch them all and run validation
234219
// Run form validation
235220
// Submit the form
236221

237222
this.store.setState((old) => ({
238223
...old,
239-
// Submittion attempts mark the form as not submitted
224+
// Submission attempts mark the form as not submitted
240225
isSubmitted: false,
241226
// Count submission attempts
242227
submissionAttempts: old.submissionAttempts + 1,

packages/react-form/src/index.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ export type {
2222

2323
export { FormApi, FieldApi, functionalUpdate } from '@tanstack/form-core'
2424

25-
export type { FormProps } from './useForm'
2625
export { useForm } from './useForm'
2726

2827
export type { UseField, FieldComponent } from './useField'

packages/react-form/src/useForm.tsx

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -6,17 +6,10 @@ import React from 'react'
66
import { type UseField, type FieldComponent, Field, useField } from './useField'
77
import { formContext } from './formContext'
88

9-
export type FormSubmitEvent = React.FormEvent<HTMLFormElement>
10-
119
declare module '@tanstack/form-core' {
12-
interface Register {
13-
FormSubmitEvent: FormSubmitEvent
14-
}
15-
1610
// eslint-disable-next-line no-shadow
1711
interface FormApi<TFormData> {
1812
Provider: (props: { children: any }) => any
19-
getFormProps: () => FormProps
2013
Field: FieldComponent<TFormData, TFormData>
2114
useField: UseField<TFormData>
2215
useStore: <TSelected = NoInfer<FormState<TFormData>>>(
@@ -31,11 +24,6 @@ declare module '@tanstack/form-core' {
3124
}
3225
}
3326

34-
export type FormProps = {
35-
onSubmit: (e: FormSubmitEvent) => void
36-
disabled: boolean
37-
}
38-
3927
export function useForm<TData>(opts?: FormOptions<TData>): FormApi<TData> {
4028
const [formApi] = React.useState(() => {
4129
// @ts-ignore
@@ -45,12 +33,6 @@ export function useForm<TData>(opts?: FormOptions<TData>): FormApi<TData> {
4533
api.Provider = (props) => (
4634
<formContext.Provider {...props} value={{ formApi: api }} />
4735
)
48-
api.getFormProps = () => {
49-
return {
50-
onSubmit: formApi.handleSubmit,
51-
disabled: api.state.isSubmitting,
52-
}
53-
}
5436
api.Field = Field as any
5537
api.useField = useField as any
5638
api.useStore = (

tsconfig.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
"esModuleInterop": true,
1313
"forceConsistentCasingInFileNames": true,
1414
"isolatedModules": true,
15-
"lib": ["DOM", "DOM.Iterable", "ES2020"],
15+
"lib": ["ES2020"],
1616
"module": "ES2020",
1717
"moduleResolution": "node",
1818
"noImplicitAny": true,

0 commit comments

Comments
 (0)