Overview
The Smart Form component provides a complete form solution with Zod schema validation, TanStack Query integration for mutations, and support for multiple field types. It automatically handles loading states, error handling, and cache invalidation.
Installation
npx shadcn@latest add https://rigidui.com/r/smart-form.json
Usage
import { SmartForm , SmartFormField } from "@/components/smart-form"
import { z } from "zod"
const userSchema = z . object ({
name: z . string (). min ( 2 , "Name must be at least 2 characters" ),
email: z . string (). email ( "Invalid email address" ),
role: z . enum ([ "admin" , "user" , "moderator" ]),
isActive: z . boolean (),
})
type UserFormData = z . infer < typeof userSchema >
export default function MyForm () {
const handleSubmit = async ( data : UserFormData ) => {
await new Promise ( resolve => setTimeout ( resolve , 1000 ))
console . log ( 'Form submitted:' , data )
return { success: true , data }
}
return (
< div className = "max-w-md" >
< SmartForm
schema = { userSchema }
mutationFn = { handleSubmit }
onSuccess = { ( data ) => console . log ( "Success:" , data ) }
>
{ ( form ) => (
<>
< SmartFormField
form = { form }
name = "name"
type = "text"
label = "Name"
placeholder = "Enter your name"
/>
< SmartFormField
form = { form }
name = "email"
type = "email"
label = "Email"
placeholder = "Enter your email"
/>
< SmartFormField
form = { form }
name = "role"
type = "select"
label = "Role"
options = { [
{ value: "admin" , label: "Admin" },
{ value: "user" , label: "User" },
{ value: "moderator" , label: "Moderator" },
] }
/>
< SmartFormField
form = { form }
name = "isActive"
type = "checkbox"
label = "Active user"
/>
</>
) }
</ SmartForm >
</ div >
)
}
import { SmartForm , SmartFormField } from "@/components/smart-form"
import { z } from "zod"
const schema = z . object ({
name: z . string (). min ( 2 ),
email: z . string (). email (),
})
export default function MyForm () {
const handleSubmit = async ( data ) => {
const response = await fetch ( '/api/users' , {
method: 'POST' ,
body: JSON . stringify ( data ),
})
return response . json ()
}
return (
< SmartForm
schema = { schema }
mutationFn = { handleSubmit }
queryKey = { [ 'users' ] }
>
{ ( form ) => (
<>
< SmartFormField form = { form } name = "name" type = "text" label = "Name" />
< SmartFormField form = { form } name = "email" type = "email" label = "Email" />
</>
) }
</ SmartForm >
)
}
Features
Zod Schema Validation Built-in integration with Zod for runtime type safety and comprehensive validation rules.
TanStack Query Integration Seamless integration with TanStack Query for mutations, loading states, and cache invalidation.
Multiple Field Types Support for text, email, password, number, textarea, select, checkbox, radio, and color field types.
TypeScript Support Full TypeScript support with type inference from Zod schemas for complete type safety.
Conditional Fields Show/hide fields based on other field values using the ConditionalField component.
Form Sections Organize complex forms into logical sections with titles and descriptions.
API Reference
The main form component that handles validation, submission, and state management.
Zod schema for form validation and type safety.
mutationFn
(data: T) => Promise<any>
required
Async function to handle form submission (API call).
children
(form: UseFormReturn<T>) => React.ReactNode
required
Render function that receives the form instance for building form fields.
TanStack Query key for cache invalidation after successful submission.
mode
'create' | 'edit'
default: "'create'"
Form mode that affects submit button text and behavior.
Default values for form fields.
Callback function called on successful form submission.
Callback function called when form submission fails.
Custom text for submit button (overrides mode-based text).
Additional CSS classes for the form container.
Renders individual form fields with appropriate input components.
React Hook Form instance passed from SmartForm.
Field name that matches the schema property.
type
'text' | 'email' | 'password' | 'number' | 'textarea' | 'select' | 'checkbox' | 'radio' | 'color'
required
Input type that determines the rendered field component.
Label text displayed above the field.
Placeholder text for input fields.
Help text displayed below the field.
options
FormFieldOption[]
default: "[]"
Options for select and radio field types.
Whether the field is disabled.
Additional CSS classes for the field container.
ConditionalField
Conditionally renders fields based on other field values.
React Hook Form instance passed from SmartForm.
The field name to watch for changes.
The value to compare against the watched field.
Content to render when the condition is met.
Groups related fields into logical sections.
The title text displayed for the form section.
Form fields and other content to display in the section.
Optional description text displayed below the title.
Additional CSS classes for styling the section.
TypeScript Interfaces
interface SmartFormProps < T extends FieldValues = FieldValues > {
schema : z . ZodSchema < T >
mutationFn : ( data : T ) => Promise < any >
queryKey ?: string []
mode ?: 'create' | 'edit'
defaultValues ?: Partial < T >
onSuccess ?: ( data : any ) => void
onError ?: ( error : Error ) => void
submitText ?: string
className ?: string
children : ( form : UseFormReturn < T >) => React . ReactNode
}
interface FormFieldOption {
value : string
label : string
}
Advanced Examples
Conditional Fields
import { SmartForm , SmartFormField , ConditionalField } from "@/components/smart-form"
import { z } from "zod"
const schema = z . object ({
role: z . enum ([ "admin" , "user" ]),
adminCode: z . string (). optional (),
email: z . string (). email (),
})
export default function ConditionalForm () {
return (
< SmartForm schema = { schema } mutationFn = { handleSubmit } >
{ ( form ) => (
<>
< SmartFormField form = { form } name = "role" type = "select" label = "Role"
options = { [
{ value: "admin" , label: "Admin" },
{ value: "user" , label: "User" },
] }
/>
< ConditionalField form = { form } when = "role" equals = "admin" >
< SmartFormField
form = { form }
name = "adminCode"
type = "password"
label = "Admin Code"
description = "Required for admin access"
/>
</ ConditionalField >
< SmartFormField form = { form } name = "email" type = "email" label = "Email" />
</>
) }
</ SmartForm >
)
}
import { SmartForm , SmartFormField , FormSection } from "@/components/smart-form"
import { z } from "zod"
const schema = z . object ({
firstName: z . string (),
lastName: z . string (),
email: z . string (). email (),
company: z . string (),
position: z . string (),
})
export default function SectionedForm () {
return (
< SmartForm schema = { schema } mutationFn = { handleSubmit } >
{ ( form ) => (
<>
< FormSection title = "Personal Information" description = "Basic details about you" >
< SmartFormField form = { form } name = "firstName" type = "text" label = "First Name" />
< SmartFormField form = { form } name = "lastName" type = "text" label = "Last Name" />
< SmartFormField form = { form } name = "email" type = "email" label = "Email" />
</ FormSection >
< FormSection title = "Professional Information" description = "Your work details" >
< SmartFormField form = { form } name = "company" type = "text" label = "Company" />
< SmartFormField form = { form } name = "position" type = "text" label = "Position" />
</ FormSection >
</>
) }
</ SmartForm >
)
}
The SmartForm component automatically handles form state management, validation, and submission. You only need to focus on defining your schema and fields.
When using with TanStack Query, provide a queryKey to automatically invalidate cached data after successful form submission.
Always validate data on the server-side in addition to client-side Zod validation for security purposes.