UI Lab

    Form Variants

    Different form layouts and patterns β€” switch stack and implementation mode (JSON Config or Static JSX), then pick a variant. Each demo uses FormConfig with React Hook Form, TanStack Form, or useActionState. Install per variant, e.g. npx afnoui add forms/forms-contact.

    Install with:
    npx afnoui add forms/forms-job-application
    Job Application

    Senior Software Engineer

    Join our engineering team and build amazing products

    Personal Information

    Application Details

    Click to upload or drag and drop

    Submitted data

    Waiting for a submit…

    Submit the form above to see the validated payload rendered here.

    Source Code

    Required Dependencies & Files

    Install packages and copy 13 files to run this form

    Dependencies

    react-hook-form@hookform/resolverszodaxioslucide-react@tanstack/react-query

    Dev Dependencies

    typescript@types/react@types/react-dom

    πŸ’‘ Using CLI? Shared files are auto-installed

    Run npx afnoui form init (or pnpm dlx / yarn dlx / bunx) to scaffold all ● shared files for this stack. You only need to copy ● variant-specific files for your form.

    ● Variant-specificformConfig.ts, MyFormPage.tsx, formSchema.ts β€” regenerated per form● Sharedtypes.ts, ReactHookForm.tsx, ReactHookFormField.tsx, … useBackendErrors.ts, field components β€” install via CLI or copy once
    πŸ“@/pages/MyFormPage.tsxvariant-specific
    Form page component
    import { useMemo } from "react";
    import { ReactHookForm } from "@/components/forms/react-hook-form";
    import { BackendErrorResponse } from "@/hooks/useBackendErrors";
    import { formService } from "./formService";
    import { formConfig } from "./formConfig";
    import { formSchema } from "./formSchema";
    
    export default function MyFormPage() {
      const schema = formSchema;
    
      const handleSubmit = async (data: Record<string, unknown>) => {
        await formService.submitForm(data);
      };
    
      return (
        <div className="container mx-auto py-8 max-w-3xl">
          <ReactHookForm config={formConfig} schema={schema} onSubmit={handleSubmit} />
        </div>
      );
    }