Note: This project is still in development and has not been publicly released. Coming soon.
Docs
Smart Form
Smart Form

A comprehensive form component inspired by Stripe's checkout experience that automatically generates forms from field definitions with built-in Zod validation, multiple input types, and advanced features like field grouping and conditional visibility.

27 views
2 downloads
Loading...

Overview

The Smart Form component provides a declarative way to build complex forms with minimal boilerplate, drawing inspiration from Stripe's polished checkout experience and modern UI/UX design principles. Like Stripe's forms, it emphasizes clarity, progressive disclosure, and intuitive user flows that reduce friction and abandonment rates.

The component combines elegant visual design with robust functionality, supporting multiple input types, automatic validation with Zod schemas, field grouping, conditional visibility, and customizable layouts. Its design philosophy prioritizes user experience through thoughtful defaults, accessible interactions, and smooth validation feedback that guides users toward successful form completion.

Installation

pnpm dlx shadcn@latest add https://deltacomponents.dev/r/smart-form.json

Usage

1"use client"
2
3import { z } from "zod"
4
5import { FieldDefinition, SmartForm } from "@/registry/blocks/smart-form"
6
7const schema = z.object({
8 email: z.string().email("Please enter a valid email"),
9 password: z.string().min(8, "Password must be at least 8 characters"),
10})
11
12const fields: FieldDefinition[] = [
13 {
14 name: "email",
15 label: "Email",
16 type: "email",
17 required: true,
18 placeholder: "Enter your email",
19 },
20 {
21 name: "password",
22 label: "Password",
23 type: "password",
24 required: true,
25 placeholder: "Enter your password",
26 },
27]
28
29export function LoginForm() {
30 const handleSubmit = async (data: z.infer<typeof schema>) => {
31 console.log("Form data:", data)
32 }
33
34 return (
35 <SmartForm
36 fields={fields}
37 schema={schema}
38 onSubmit={handleSubmit}
39 submitText="Sign In"
40 />
41 )
42}

API Reference

SmartForm Props

NameTypeDefaultDescription
fieldsFieldDefinition[]-Array of field definitions that define the form structure
schemaZodSchema-Zod schema for form validation
onSubmit(data: any) => Promise<void> | void-Function called when form is submitted with valid data
submitTextstring"Submit"Text displayed on the submit button
cancelTextstring"Cancel"Text displayed on the cancel button
onCancel() => void-Function called when cancel button is clicked
classNamestring-Additional CSS classes for the form container
fieldClassNamestring-CSS classes applied to each field container
submitClassNamestring-CSS classes for the submit button
cancelClassNamestring-CSS classes for the cancel button
layout"vertical" | "horizontal" | "grid""vertical"Form layout style
columnsnumber1Number of columns for grid layout
gapnumber6Gap between form elements
loadingbooleanfalseWhether the form is in loading state
defaultValuesRecord<string, any>{}Default values for form fields
successMessagestring-Message displayed on successful submission
errorMessagestring-Message displayed on submission error
resetOnSuccessbooleanfalseWhether to reset form after successful submission
hideSubmitButtonbooleanfalseWhether to hide the submit button
renderCustomField(field, formState, handleChange) => ReactNode-Custom renderer for custom field types

FieldDefinition

Base Properties

NameTypeDefaultDescription
namestring-Unique field identifier
labelstring-Field label text
typeFieldType-Type of input field
requiredbooleanfalseWhether the field is required
disabledbooleanfalseWhether the field is disabled
descriptionstring-Description text below the label
hintstring-Hint text below the input
labelVariant"default" | "muted""default"Style variant for the label
classNamestring-CSS classes for the field container
hiddenboolean | (values) => booleanfalseWhether to hide the field or conditional function
groupstring-Group name for field grouping
widthstring | number-Custom width for the field

Field Types

The component supports these field types:

  • Text Fields: text, email, password, number, tel, url
  • Selection: select, radio, checkbox, switch
  • Input: textarea, date, file, otp, tags
  • Custom: custom (with custom renderer)

Variants

Most input types support these variants:

  • default: Standard shadcn/ui styling with shadows and borders
  • pill: Rounded styling with muted background

Special Properties by Type

Text Fields (text, email, password, etc.):

  • placeholder: Placeholder text
  • defaultValue: Default text value
  • variant: Input variant style

Select Fields:

  • options: Array of {value, label, disabled?} objects
  • placeholder: Placeholder text
  • defaultValue: Default selected value

Radio Fields:

  • options: Array of {value, label, description?, disabled?} objects
  • orientation: "vertical" | "horizontal"
  • defaultValue: Default selected value

Checkbox/Switch Fields:

  • defaultChecked: Default checked state
  • variant: For switch: "pill" | "rectangular"

Textarea Fields:

  • placeholder: Placeholder text
  • rows: Number of text rows
  • defaultValue: Default text value
  • size: "sm" | "md" | "lg"

Date Fields:

  • placeholder: Placeholder text
  • defaultValue: Default date value
  • minDate: Minimum selectable date
  • maxDate: Maximum selectable date
  • dateFormat: Date format string

File Fields:

  • accept: Accepted file types
  • multiple: Allow multiple files
  • maxSize: Maximum file size in bytes
  • maxFiles: Maximum number of files
  • showPreviews: Show file previews
  • showIcons: Show file type icons

OTP Fields:

  • length: Number of digits (default: 6)
  • maskChar: Character for masking
  • mask: Whether to mask input
  • autoFocus: Auto focus first input
  • separator: Show separators between groups
  • groupSize: Size of each group
  • autoSubmit: Auto submit when complete
  • onComplete: Callback when OTP is complete

Tags Fields:

  • defaultValue: Array of default tags
  • triggerKey: Key to trigger tag creation ("Enter" | "Space" | "Comma")

Features

Field Grouping

Group related fields together by setting the group property:

1const fields = [
2 { name: "firstName", label: "First Name", type: "text", group: "name" },
3 { name: "lastName", label: "Last Name", type: "text", group: "name" },
4]

Conditional Visibility

Show/hide fields based on form values:

1const fields = [
2 { name: "hasAccount", label: "I have an account", type: "checkbox" },
3 {
4 name: "password",
5 label: "Password",
6 type: "password",
7 hidden: (values) => !values.hasAccount,
8 },
9]

Custom Field Rendering

Implement custom field types with the renderCustomField prop:

1<SmartForm
2 fields={fields}
3 schema={schema}
4 onSubmit={handleSubmit}
5 renderCustomField={(field, formState, handleChange) => {
6 if (field.type === "custom") {
7 return <CustomComponent {...field} onChange={handleChange} />
8 }
9 }}
10/>

Examples

Pill Variant

Loading...

Registration Form

A comprehensive example showing multiple field types, grouping, validation, switch inputs, and tags input:

Loading...