Auto Form

Component creates form based on Zod schemas & react-hook-form with validation

Basic Usage

import { z } from 'zod';
import { AutoForm } from 'vitnode/components/form/auto-form';
import { AutoFormInput } from 'vitnode/components/form/fields/input';
const formSchema = z.object({
  username: z.string(),
});
<AutoForm
  fields={[
    {
      id: 'username',
      component: props => (
        <AutoFormInput
          description="This is the username for your application. It should be unique and not shared with anyone."
          label="Username"
          {...props}
        />
      ),
    },
  ]}
  formSchema={formSchema}
/>

Zod Schema Configuration

Auto Form is deeply integrated with Zod, supporting Zod validators. HTML input attributes are automatically applied based on your schema constraints.

Required vs Optional Fields

By default, all fields are required. Make a field optional using the optional method:

const formSchema = z.object({
  username: z.string(), // Required field
  bio: z.string().optional(), // Optional field
});

Default Values

Set default values for fields using the default method:

const formSchema = z.object({
  username: z.string().default('user123'),
  role: z.enum(['user', 'admin']).default('user'),
});

Advanced Validation

Auto Form supports all Zod validators:

const formSchema = z.object({
  username: z.string().min(3).max(20),
  email: z.string().email(),
  age: z.number().min(18).max(120),
  password: z
    .string()
    .min(8)
    .refine(val => /[A-Z]/.test(val), {
      message: 'Password must contain at least one uppercase letter',
    }),
});

Form Submission

To activate submit button and handle form submission with the onSubmit callback:

<AutoForm
  fields={[
    {
      id: 'username',
      component: props => (
        <AutoFormInput
          description="This is the username for your application."
          label="Username"
          {...props}
        />
      ),
    },
  ]}
  formSchema={formSchema}
  onSubmit={values => {
    // Handle form submission
  }}
/>

Accessing the Form Instance

The onSubmit callback provides access to the React Hook Form instance as a second parameter:

<AutoForm
  fields={
    [
      /* ...field definitions */
    ]
  }
  formSchema={formSchema}
  onSubmit={(values, form) => {
    // Access form methods
    form.setError('username', {
      type: 'manual',
      message: 'Username already taken',
    });
  }}
/>

You can also define the submission handler separately:

const onSubmit = async (
  values: z.infer<typeof formSchema>,
  form: UseFormReturn<z.infer<typeof formSchema>>,
) => {
  try {
    await saveData(values);
    toast.success('Form submitted successfully');
  } catch (error) {
    form.setError('root', {
      type: 'manual',
      message: 'Failed to submit form',
    });
  }
};
 
// Then in your component
<AutoForm
  fields={
    [
      /* ...field definitions */
    ]
  }
  formSchema={formSchema}
  onSubmit={onSubmit}
/>;

Customizing the Submit Button

Customize the submit button using the submitButtonProps:

<AutoForm
  fields={
    [
      /* ...field definitions */
    ]
  }
  formSchema={formSchema}
  submitButtonProps={{
    variant: 'outline',
    size: 'lg',
    children: 'Save Changes',
    className: 'w-full mt-4',
  }}
  onSubmit={values => {
    console.log('Form submitted', values);
  }}
/>

Form Layout and Styling

You can control the form layout using standard CSS techniques:

<AutoForm
  className="grid grid-cols-1 gap-4 md:grid-cols-2"
  fields={
    [
      /* ...field definitions */
    ]
  }
  formSchema={formSchema}
/>

On this page