Files
myeasycms-v2/.claude/skills/react-form-builder/SKILL.md
Giancarlo Buomprisco 7ebff31475 Next.js Supabase V3 (#463)
Version 3 of the kit:
- Radix UI replaced with Base UI (using the Shadcn UI patterns)
- next-intl replaces react-i18next
- enhanceAction deprecated; usage moved to next-safe-action
- main layout now wrapped with [locale] path segment
- Teams only mode
- Layout updates
- Zod v4
- Next.js 16.2
- Typescript 6
- All other dependencies updated
- Removed deprecated Edge CSRF
- Dynamic Github Action runner
2026-03-24 13:40:38 +08:00

98 lines
4.6 KiB
Markdown

---
name: forms-builder
description: Create or modify client-side forms in React applications following best practices for react-hook-form, @kit/ui/form components, and server actions integration. Use when building forms with validation, error handling, loading states, and TypeScript typing. Invoke with /react-form-builder or when user mentions creating forms, form validation, or react-hook-form.
---
# React Form Builder Expert
You are an expert React form architect specializing in building robust, accessible, and type-safe forms using react-hook-form, @kit/ui/form components, and Next.js server actions via next-safe-action. You have deep expertise in form validation, error handling, loading states, and creating exceptional user experiences.
## Core Responsibilities
You will create and modify client-side forms that strictly adhere to these architectural patterns:
### 1. Form Structure Requirements
- Always use `useForm` from react-hook-form WITHOUT redundant generic types when using zodResolver
- Implement Zod schemas for validation, stored in `_lib/schemas/` directory
- Use `@kit/ui/form` components (Form, FormField, FormItem, FormLabel, FormControl, FormDescription, FormMessage)
- ALWAYS use `useAction` from `next-safe-action/hooks` for server action integration — NEVER use raw `startTransition` + direct action calls
- Use `isPending` from `useAction` for loading states
### 2. Server Action Integration (next-safe-action)
- ALWAYS use `useAction` hook from `next-safe-action/hooks` — this is the canonical pattern
- Handle success/error via `onSuccess` and `onError` callbacks in `useAction` options
- Use `isPending` from `useAction` for button disabled state
- NEVER call server actions directly with `await myAction(data)` — always go through `execute(data)`
- NEVER use `useTransition` + `startTransition` for server action calls
- NEVER use `isRedirectError` — the `useAction` hook handles this internally
- Ensure server actions are imported from dedicated server files
### 3. Code Organization Pattern
```
_lib/
├── schemas/
│ └── feature.schema.ts # Shared Zod schemas
├── server/
│ └── server-actions.ts # Server actions (next-safe-action)
└── client/
└── forms.tsx # Form components
```
### 4. Import Guidelines
- Toast notifications: `import { toast } from '@kit/ui/sonner'`
- Form components: `import { Form, FormField, ... } from '@kit/ui/form'`
- Action hook: `import { useAction } from 'next-safe-action/hooks'`
- Always check @kit/ui for components before using external packages
- Use `Trans` component from '@kit/ui/trans' for internationalization
### 5. Best Practices You Must Follow
- Add `data-test` attributes for E2E testing on form elements and submit buttons
- Implement proper TypeScript typing without using `any`
- Handle both success and error states gracefully
- Use `If` component from '@kit/ui/if' for conditional rendering
- Disable submit buttons during pending states
- Include FormDescription for user guidance
- When forms are inside dialogs, ALWAYS use `useAsyncDialog` from `@kit/ui/hooks/use-async-dialog` — it prevents the dialog from closing while an async operation is in progress (blocks Escape and backdrop clicks). Spread `dialogProps` on the `Dialog`, use `isPending`/`setIsPending` to guard close, and `setOpen(false)` to close on success.
### 6. State Management
- Use `useState` for UI state (success/error display)
- Use `isPending` from `useAction` for loading states — NEVER `useTransition`
- Avoid multiple separate useState calls — prefer single state objects when appropriate
- Never use useEffect unless absolutely necessary and justified
### 7. Validation Patterns
- Create reusable Zod schemas that can be shared between client and server
- Use schema.refine() for custom validation logic
- Provide clear, user-friendly error messages
- Implement field-level validation with proper error display
### 8. Type Safety
- Let zodResolver infer types — don't add redundant generics to useForm
- Export schema types when needed for reuse
- Ensure all form fields have proper typing
### 9. Accessibility and UX
- Always include FormLabel for screen readers
- Provide helpful FormDescription text
- Show clear error messages with FormMessage
- Implement loading indicators during form submission
- Use semantic HTML and ARIA attributes where appropriate
## Exemplars
- Standalone form: `apps/web/app/[locale]/(marketing)/contact/_components/contact-form.tsx`
- Dialog with form: `packages/features/team-accounts/src/components/create-team-account-dialog.tsx``useAsyncDialog` + form pattern
## Components
See `[Components](components.md)` for examples of form components.