Skip to content

form-generator

Generate React forms with validation, state management, and submission handling using react-hook-form and zod.

From plugin
f5-framework
24104 skills104 agents69 commands
Install
$ npx -y skills add Fujigo-Software/f5-framework-claude --agent claude-code

How it fires

How this agent gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
  • You can call itInvoke it directly when you want it.

Context preview

The summary Claude sees to decide when to auto-load this agent.

Generate React forms with validation, state management, and submission handling using react-hook-form and zod.

Agent definition

form-generator.md

React Form Generator Agent

Purpose

Generate React forms with validation, state management, and submission handling using react-hook-form and zod.

Triggers

  • "create form"
  • "generate form"
  • "react form"
  • "validation form"

Input Requirements

required:
  - form_name: string         # PascalCase form name
  - fields: array             # Form field definitions

optional:
  - entity: string            # Related entity name
  - mode: string              # 'create' | 'edit' | 'both'
  - submit_endpoint: string   # API endpoint
  - on_success: string        # Success callback behavior
  - reset_on_submit: boolean  # Reset form after submit

Field Definition

field:
  name: string                # Field name (camelCase)
  type: string                # text | email | password | number | select | checkbox | textarea | date | file
  label: string               # Display label
  placeholder: string         # Placeholder text
  required: boolean           # Is required
  validation:                 # Zod validation rules
    min: number
    max: number
    pattern: string
    custom: string            # Custom validation message
  options: array              # For select fields
  defaultValue: any           # Default value

Generation Process

1. Analyze Schema

  • Parse field definitions
  • Generate Zod schema
  • Determine form structure

2. Generate Components

Schema File

// src/features/{feature}/schemas/{entity}.schema.ts
import { z } from 'zod';

export const {entity}Schema = z.object({
  name: z
    .string()
    .min(2, 'Name must be at least 2 characters')
    .max(100, 'Name must be less than 100 characters'),
  email: z
    .string()
    .email('Invalid email address'),
  description: z
    .string()
    .max(500, 'Description must be less than 500 characters')
    .optional(),
  category: z
    .string()
    .min(1, 'Please select a category'),
  price: z
    .number()
    .min(0, 'Price must be positive')
    .optional(),
  isActive: z
    .boolean()
    .default(true),
});

export type {Entity}FormValues = z.infer<typeof {entity}Schema>;

// Partial schema for updates
export const {entity}UpdateSchema = {entity}Schema.partial();
export type {Entity}UpdateFormValues = z.infer<typeof {entity}UpdateSchema>;

Form Component

// src/features/{feature}/components/{Entity}Form.tsx
import { useForm } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod';
import { Button } from '@/components/ui/Button';
import { Input } from '@/components/ui/Input';
import { Textarea } from '@/components/ui/Textarea';
import { Select } from '@/components/ui/Select';
import { Checkbox } from '@/components/ui/Checkbox';
import {
  Form,
  FormControl,
  FormDescription,
  FormField,
  FormItem,
  FormLabel,
  FormMessage,
} from '@/components/ui/Form';
import { {entity}Schema, type {Entity}FormValues } from '../schemas/{entity}.schema';

interface {Entity}FormProps {
  defaultValues?: Partial<{Entity}FormValues>;
  onSubmit: (data: {Entity}FormValues) => Promise<void>;
  onCancel?: () => void;
  isSubmitting?: boolean;
  mode?: 'create' | 'edit';
}

export function {Entity}Form({
  defaultValues,
  onSubmit,
  onCancel,
  isSubmitting = false,
  mode = 'create',
}: {Entity}FormProps) {
  const form = useForm<{Entity}FormValues>({
    resolver: zodResolver({entity}Schema),
    defaultValues: {
      name: '',
      email: '',
      description: '',
      category: '',
      isActive: true,
      ...defaultValues,
    },
  });

  const handleSubmit = async (data: {Entity}FormValues) => {
    try {
      await onSubmit(data);
      if (mode === 'create') {
        form.reset();
      }
    } catch (error) {
      // Error handling done in parent
    }
  };

  return (
    <Form {...form}>
      <form onSubmit={form.handleSubmit(handleSubmit)} className="space-y-6">
        <FormField
          control={form.control}
          name="name"
          render={({ field }) => (
            <FormItem>
              <FormLabel>Name</FormLabel>
              <FormControl>
                <Input placeholder="Enter name" {...field} />
              </FormControl>
              <FormDescription>
                This is the display name.
              </FormDescription>
              <FormMessage />
            </FormItem>
          )}
        />

        <FormField
          control={form.control}
          name="email"
          render={({ field }) => (
            <FormItem>
              <FormLabel>Email</FormLabel>
              <FormControl>
                <Input type="email" placeholder="email@example.com" {...field} />
              </FormControl>
              <FormMessage />
            </FormItem>
          )}
        />

        <FormField
          control={form.control}
          name="description"
          render={({ field }) => (
            <FormItem>
              <FormLabel>Description</FormLabel>
              <FormControl>
                <Textarea
                  placeholder="Enter description..."
                  rows={4}
                  {...field}
                />
              </FormControl>
              <FormMessage />
            </FormItem>
          )}
        />

        <FormField
          control={form.control}
          name="category"
          render={({ field }) => (
            <FormItem>
              <FormLabel>Category</FormLabel>
              <Select value={field.value} onValueChange={field.onChange}>
                <Select.Trigger>
                  <Select.Value placeholder="Select category" />
                </Select.Trigger>
                <Select.Content>
                  <Select.Item value="category1">Category 1</Select.Item>
                  <Select.Item value="category2">Category 2</Select.Item>
                </Select.Content>
              </Select>
              <FormMessage />
            </FormItem>
          )}
        />

        <FormField
          control
Read more
Ships withf5-framework

AI-Powered Development Framework for Claude Code

Get the whole plugin, auto-invoked
Stats
24
Stars
0
Views
8
Forks
Quiet
Maintenance
Python
Language
MIT
License
6mo ago
Last commit
6mo ago
Created

Repo: Fujigo-Software/f5-framework-claude