Skip to content

Commit b2664aa

Browse files
committed
chore: add working number demo
1 parent 123ba59 commit b2664aa

File tree

5 files changed

+49
-30
lines changed

5 files changed

+49
-30
lines changed

examples/react/simple/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@
1212
"@mantine/core": "7.13.5",
1313
"@tanstack/react-form": "^0.41.0",
1414
"react": "^18.3.1",
15-
"react-dom": "^18.3.1"
15+
"react-dom": "^18.3.1",
16+
"zod": "^3.24.0"
1617
},
1718
"devDependencies": {
1819
"@types/react": "^18.3.3",

examples/react/simple/src/app-form.tsx

Lines changed: 27 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -52,12 +52,35 @@ function TextField({ label }: TextFieldProps) {
5252
)
5353
}
5454

55+
interface NumberFieldProps {
56+
label: string
57+
}
58+
59+
function NumberField({ label }: NumberFieldProps) {
60+
const field = useFieldContext()
61+
return (
62+
<TextInput
63+
value={field.state.value}
64+
onChange={(e) => field.setValue(e.currentTarget.valueAsNumber)}
65+
label={label}
66+
type="number"
67+
error={
68+
field.state.meta.errors.length > 0 ? field.state.meta.errors[0] : null
69+
}
70+
defaultValue={field.options.defaultValue}
71+
/>
72+
)
73+
}
74+
75+
const FieldComponents = {
76+
TextField,
77+
NumberField,
78+
} as const
79+
5580
type AppField<TFormData> = FieldComponent<
5681
TFormData,
5782
ValidatorType,
58-
{
59-
TextField: typeof TextField
60-
}
83+
typeof FieldComponents
6184
>
6285

6386
export function useAppForm<TFormData>(
@@ -74,11 +97,7 @@ export function useAppForm<TFormData>(
7497
<form.Field {...props}>
7598
{(field) => (
7699
<FormFieldContext.Provider value={field}>
77-
{children(
78-
Object.assign(field, {
79-
TextField,
80-
}),
81-
)}
100+
{children(Object.assign(field, FieldComponents))}
82101
</FormFieldContext.Provider>
83102
)}
84103
</form.Field>

examples/react/simple/src/index.tsx

Lines changed: 17 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,24 @@
11
import * as React from 'react'
22
import { createRoot } from 'react-dom/client'
33
import { MantineProvider } from '@mantine/core'
4+
import { z } from 'zod'
45
import { useAppForm } from './app-form.tsx'
56

7+
const formSchema = z.object({
8+
name: z.string(),
9+
age: z.number().gte(13, 'You must be 13 to make an account'),
10+
})
11+
12+
type FormValues = z.infer<typeof formSchema>
13+
614
export default function App() {
715
const form = useAppForm({
816
defaultValues: {
9-
firstName: '',
10-
lastName: '',
17+
name: '',
18+
age: 0,
19+
} as FormValues,
20+
validators: {
21+
onChange: formSchema,
1122
},
1223
onSubmit: async ({ value }) => {
1324
// Do something with form data
@@ -28,32 +39,17 @@ export default function App() {
2839
<div>
2940
{/* A type-safe field component*/}
3041
<form.AppField
31-
name="firstName"
32-
validators={{
33-
onChange: ({ value }) =>
34-
!value
35-
? 'A first name is required'
36-
: value.length < 3
37-
? 'First name must be at least 3 characters'
38-
: undefined,
39-
onChangeAsyncDebounceMs: 500,
40-
onChangeAsync: async ({ value }) => {
41-
await new Promise((resolve) => setTimeout(resolve, 1000))
42-
return (
43-
value.includes('error') && 'No "error" allowed in first name'
44-
)
45-
},
46-
}}
42+
name="name"
4743
children={(field) => {
4844
// Avoid hasty abstractions. Render props are great!
49-
return <field.TextField label="First Name" />
45+
return <field.TextField label="Your Name" />
5046
}}
5147
/>
5248
</div>
5349
<div>
5450
<form.AppField
55-
name="lastName"
56-
children={(field) => <field.TextField label="Last Name" />}
51+
name="age"
52+
children={(field) => <field.NumberField label="Your Age" />}
5753
/>
5854
</div>
5955
<form.Subscribe

examples/react/simple/src/lib.ts

Whitespace-only changes.

pnpm-lock.yaml

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)