TanStack Form
Building forms with TanStack Form and radk.
radk components are fully compatible with TanStack Form.
Installation
npm install @tanstack/react-form zod @tanstack/zod-form-adapterBasic Form
"use client"
import { useForm } from "@tanstack/react-form"
import { zodValidator } from "@tanstack/zod-form-adapter"
import { z } from "zod"
import { Button } from "@/components/ui/button"
import { Input } from "@/components/ui/input"
import { Label } from "@/components/ui/label"
export function SignupForm() {
const form = useForm({
defaultValues: { email: "", username: "" },
validatorAdapter: zodValidator(),
onSubmit: async ({ value }) => {
console.log(value)
},
})
return (
<form
onSubmit={(e) => {
e.preventDefault()
form.handleSubmit()
}}
className="space-y-4"
>
<form.Field
name="email"
validators={{ onChange: z.string().email("Enter a valid email") }}
>
{(field) => (
<div className="grid gap-1.5">
<Label htmlFor={field.name}>Email</Label>
<Input
id={field.name}
type="email"
value={field.state.value}
onBlur={field.handleBlur}
onChange={(e) => field.handleChange(e.target.value)}
/>
{field.state.meta.errors.length > 0 && (
<p className="text-xs text-destructive">
{field.state.meta.errors[0]}
</p>
)}
</div>
)}
</form.Field>
<form.Field
name="username"
validators={{ onChange: z.string().min(3, "Min 3 characters") }}
>
{(field) => (
<div className="grid gap-1.5">
<Label htmlFor={field.name}>Username</Label>
<Input
id={field.name}
value={field.state.value}
onBlur={field.handleBlur}
onChange={(e) => field.handleChange(e.target.value)}
/>
{field.state.meta.errors.length > 0 && (
<p className="text-xs text-destructive">
{field.state.meta.errors[0]}
</p>
)}
</div>
)}
</form.Field>
<form.Subscribe selector={(state) => state.isSubmitting}>
{(isSubmitting) => (
<Button type="submit" disabled={isSubmitting} className="w-full">
{isSubmitting ? "Creating account..." : "Create account"}
</Button>
)}
</form.Subscribe>
</form>
)
}