RuleStack

Configs

Stacks

Compare

Diff

RuleStack

Configs

Stacks

Compare

Diff

Read API

RuleStack

Configs

Stacks

Compare

Diff

Read API

Configs/Cursor rules/chihebnabil/lovable-boilerplate

Cursor rule

.cursor/rules/forms.mdc

Form handling patterns with React Hook Form and Zod validation

Cursor rules

Quality

73/100

Scores the file, not the repository.

Length

676 words

12 headings · 6 code blocks

Repository

63

— · pushed 15 days ago

Last changed

3 days ago

First indexed 3 days ago.
chihebnabil/lovable-boilerplate/.cursor/rules/forms.mdcRawGitHub
1---
2description: Form handling patterns with React Hook Form and Zod validation
3globs: ["src/components/forms/**/*.tsx", "src/lib/validations/**/*.ts"]
4alwaysApply: false
5---
6 
7# Form Handling Rules
8 
9## React Hook Form + Zod Pattern
10 
11### Basic Form Setup
12```tsx
13// components/forms/UserForm.tsx
14interface UserFormProps {
15 onSubmit: (data: UserFormData) => void
16 initialData?: Partial<User>
17 isLoading?: boolean
18}
19 
20export const UserForm = ({ onSubmit, initialData, isLoading }: UserFormProps) => {
21 const form = useForm<UserFormData>({
22 resolver: zodResolver(userSchema),
23 defaultValues: {
24 name: initialData?.name || '',
25 email: initialData?.email || '',
26 phone: initialData?.phone || '',
27 }
28 })
29 
30 return (
31 <Form {...form}>
32 <form onSubmit={form.handleSubmit(onSubmit)} className="space-y-6">
33 <FormField
34 control={form.control}
35 name="name"
36 render={({ field }) => (
37 <FormItem>
38 <FormLabel>Full Name</FormLabel>
39 <FormControl>
40 <Input placeholder="Enter full name" {...field} />
41 </FormControl>
42 <FormMessage />
43 </FormItem>
44 )}
45 />
46
47 <FormField
48 control={form.control}
49 name="email"
50 render={({ field }) => (
51 <FormItem>
52 <FormLabel>Email</FormLabel>
53 <FormControl>
54 <Input type="email" placeholder="Enter email" {...field} />
55 </FormControl>
56 <FormMessage />
57 </FormItem>
58 )}
59 />
60
61 <Button type="submit" disabled={isLoading} className="w-full">
62 {isLoading ? 'Saving...' : 'Save User'}
63 </Button>
64 </form>
65 </Form>
66 )
67}
68```
69 
70### Form Hook Pattern
71```tsx
72// hooks/useUserForm.ts
73export const useUserForm = (userId?: string) => {
74 const { data: user } = useUser(userId)
75 const createUser = useCreateUser()
76 const updateUser = useUpdateUser()
77
78 const form = useForm<UserFormData>({
79 resolver: zodResolver(userSchema),
80 defaultValues: {
81 name: '',
82 email: '',
83 phone: '',
84 }
85 })
86
87 // Reset form when user data loads
88 useEffect(() => {
89 if (user) {
90 form.reset({
91 name: user.name,
92 email: user.email,
93 phone: user.phone || '',
94 })
95 }
96 }, [user, form])
97
98 const handleSubmit = (data: UserFormData) => {
99 if (userId) {
100 updateUser.mutate({ id: userId, data })
101 } else {
102 createUser.mutate(data)
103 }
104 }
105
106 const isLoading = createUser.isPending || updateUser.isPending
107
108 return {
109 form,
110 handleSubmit,
111 isLoading,
112 reset: form.reset,
113 }
114}
115```
116 
117### Advanced Form Patterns
118 
119#### Multi-Step Form
120```tsx
121// hooks/useMultiStepForm.ts
122export const useMultiStepForm = <T extends Record<string, any>>(
123 steps: Array<{ key: string; schema: ZodSchema<any> }>,
124 onComplete: (data: T) => void
125) => {
126 const [currentStep, setCurrentStep] = useState(0)
127 const [formData, setFormData] = useState<Partial<T>>({})
128
129 const currentStepConfig = steps[currentStep]
130
131 const form = useForm({
132 resolver: zodResolver(currentStepConfig.schema),
133 defaultValues: formData[currentStepConfig.key] || {}
134 })
135
136 const nextStep = (data: any) => {
137 setFormData(prev => ({ ...prev, [currentStepConfig.key]: data }))
138
139 if (currentStep < steps.length - 1) {
140 setCurrentStep(prev => prev + 1)
141 } else {
142 onComplete({ ...formData, [currentStepConfig.key]: data } as T)
143 }
144 }
145
146 const prevStep = () => {
147 if (currentStep > 0) {
148 setCurrentStep(prev => prev - 1)
149 }
150 }
151
152 return {
153 form,
154 currentStep,
155 totalSteps: steps.length,
156 isFirstStep: currentStep === 0,
157 isLastStep: currentStep === steps.length - 1,
158 nextStep,
159 prevStep,
160 handleSubmit: form.handleSubmit(nextStep)
161 }
162}
163```
164 
165#### Dynamic Form Fields
166```tsx
167// components/forms/DynamicFieldArray.tsx
168export const DynamicFieldArray = ({ name, control }: DynamicFieldArrayProps) => {
169 const { fields, append, remove } = useFieldArray({
170 control,
171 name,
172 })
173 
174 return (
175 <div className="space-y-4">
176 {fields.map((field, index) => (
177 <div key={field.id} className="flex gap-2 items-end">
178 <FormField
179 control={control}
180 name={`${name}.${index}.value`}
181 render={({ field }) => (
182 <FormItem className="flex-1">
183 <FormLabel>Item {index + 1}</FormLabel>
184 <FormControl>
185 <Input {...field} />
186 </FormControl>
187 <FormMessage />
188 </FormItem>
189 )}
190 />
191 <Button
192 type="button"
193 variant="outline"
194 size="icon"
195 onClick={() => remove(index)}
196 >
197 <X className="h-4 w-4" />
198 </Button>
199 </div>
200 ))}
201
202 <Button
203 type="button"
204 variant="outline"
205 onClick={() => append({ value: '' })}
206 >
207 <Plus className="h-4 w-4 mr-2" />
208 Add Item
209 </Button>
210 </div>
211 )
212}
213```
214 
215### Form Validation Rules
216 
217#### Complex Validation Schema
218```tsx
219// lib/validations/userProfile.ts
220export const userProfileSchema = z.object({
221 personal: z.object({
222 firstName: z.string().min(2, 'First name required'),
223 lastName: z.string().min(2, 'Last name required'),
224 email: emailSchema,
225 phone: phoneSchema.optional(),
226 dateOfBirth: z.string().optional(),
227 }),
228 address: z.object({
229 street: z.string().min(5, 'Street address required'),
230 city: z.string().min(2, 'City required'),
231 state: z.string().min(2, 'State required'),
232 zipCode: z.string().regex(/^\d{5}(-\d{4})?$/, 'Invalid zip code'),
233 country: z.string().min(2, 'Country required'),
234 }),
235 preferences: z.object({
236 newsletter: z.boolean().default(false),
237 notifications: z.boolean().default(true),
238 theme: z.enum(['light', 'dark', 'system']).default('system'),
239 })
240})
241```
242 
243#### Conditional Validation
244```tsx
245export const conditionalSchema = z.object({
246 userType: z.enum(['individual', 'business']),
247 email: emailSchema,
248 companyName: z.string().optional(),
249 taxId: z.string().optional(),
250}).refine(
251 (data) => {
252 if (data.userType === 'business') {
253 return data.companyName && data.taxId
254 }
255 return true
256 },
257 {
258 message: "Company name and tax ID required for business accounts",
259 path: ["companyName"],
260 }
261)
262```
263 
264## Form Anti-Patterns
265- Manual form state management
266- Inline validation logic
267- No error handling
268- Uncontrolled components mixing with controlled
269- No loading states during submission
270 
271## Form Best Practices
272- Always use React Hook Form + Zod
273- Extract form logic to custom hooks
274- Provide loading states during submission
275- Reset forms after successful submission
276- Handle both client and server validation errors
277 

Sections

  • Form Handling Rules
  • React Hook Form + Zod Pattern
  • Basic Form Setup
  • Form Hook Pattern
  • Advanced Form Patterns
  • Form Validation Rules
  • Form Anti-Patterns
  • Form Best Practices

What it covers

setupcode-styledo-not

Stack — with the evidence

typescript

(1.00)

react

(1.00)

supabase

(1.00)

tailwind

(1.00)

vite

(1.00)

eslint

(1.00)

node

(0.70)

javascript

(0.60)

github-actions

(0.60)

Glob targeting

  • src/components/forms/**/*.tsx
  • src/lib/validations/**/*.ts

Format

Cursor rules

The most expressive format here. Many small .mdc files, each with frontmatter declaring when it should load, so a rule about migrations only enters context when a migration is open. Costs the most to maintain and only one editor reads it.

What the corpus says about it

Repository

Owner
chihebnabil
Language
—
License
—
Archived
no

All configs in this repo

Also in chihebnabil/lovable-boilerplate

Diff this repo’s formats

One repository carrying more than one format is the comparison this product exists for: does anyone actually write different content in each file, or is one a copy of the other?

The other instruction files in this repository
RepositoryFormatStackCoversScoreChanged
chihebnabil/lovable-boilerplate.cursor/rules/design.mdc · 63Cursor rulestypescriptreact+7styleuido-not65/1003 days ago
chihebnabil/lovable-boilerplate.cursor/rules/hooks.mdc · 63Cursor rulestypescriptreact+7styleuido-not61/1003 days ago
chihebnabil/lovable-boilerplate.cursor/rules/services.mdc · 63Cursor rulestypescriptreact+7archtypesdo-not73/1003 days ago
chihebnabil/lovable-boilerplate.cursor/rules/typescript.mdc · 63Cursor rulestypescriptreact+7setupstyletypessecurity+273/1003 days ago
chihebnabil/lovable-boilerplate.github/instructions/architecture.instructions.md · 63Copilot instructionstypescriptreact+7stylearchtypesdatabase+269/1003 days ago
chihebnabil/lovable-boilerplate.github/instructions/design.instructions.md · 63Copilot instructionstypescriptreact+7lint-formatstyleuido-not61/1003 days ago
chihebnabil/lovable-boilerplate.github/instructions/development.instructions.md · 63Copilot instructionstypescriptreact+7setupbuildtestlint-format+788/1003 days ago
chihebnabil/lovable-boilerplate.github/instructions/hooks.instructions.md · 63Copilot instructionstypescriptreact+7styleui54/1003 days ago
chihebnabil/lovable-boilerplate.github/instructions/lib.instructions.md · 63Copilot instructionstypescriptreact+7archtypesdo-not69/1003 days ago
chihebnabil/lovable-boilerplate.github/instructions/pages.instructions.md · 63Copilot instructionstypescriptreact+7archuido-not69/1003 days ago
chihebnabil/lovable-boilerplate.github/instructions/quality.instructions.md · 63Copilot instructionstypescriptreact+7lint-formatdeploymentdo-not63/1003 days ago
chihebnabil/lovable-boilerplate.github/instructions/reusable.instructions.md · 63Copilot instructionstypescriptreact+7uido-notagent-behaviour32/1003 days ago
chihebnabil/lovable-boilerplateCLAUDE.md · 63CLAUDE.mdtypescriptreact+7setupbuildtestlint-format+589/1003 days ago
chihebnabil/lovable-boilerplate.cursor/rules/core.mdc · 63Cursor rulestypescriptreact+7buildlint-formatarchui+192/1003 days ago
chihebnabil/lovable-boilerplate.github/instructions/components.instructions.md · 63Copilot instructionstypescriptreact+7styleuido-not61/1003 days ago
chihebnabil/lovable-boilerplate.github/instructions/global.instructions.md · 63Copilot instructionstypescriptreact+7buildlint-formatstylearch+4100/1003 days ago
chihebnabil/lovable-boilerplate.cursor/rules/components.mdc · 63Cursor rulestypescriptreact+7stylearchuido-not65/1003 days ago
chihebnabil/lovable-boilerplate.cursor/rules/quality.mdc · 63Cursor rulestypescriptreact+7buildlint-formatstyleui+388/1003 days ago
Diff against .cursor/rules/design.mdc Diff against .cursor/rules/hooks.mdc Diff against .cursor/rules/services.mdc Diff against .cursor/rules/typescript.mdc Diff against .github/instructions/architecture.instructions.md Diff against .github/instructions/design.instructions.md Diff against .github/instructions/development.instructions.md Diff against .github/instructions/hooks.instructions.md Diff against .github/instructions/lib.instructions.md Diff against .github/instructions/pages.instructions.md Diff against .github/instructions/quality.instructions.md Diff against .github/instructions/reusable.instructions.md Diff against CLAUDE.md Diff against .cursor/rules/core.mdc Diff against .github/instructions/components.instructions.md Diff against .github/instructions/global.instructions.md Diff against .cursor/rules/components.mdc Diff against .cursor/rules/quality.mdc

Similar configs

Same format, overlapping stack, ranked by quality.

Same format, overlapping stack, ranked by quality
RepositoryFormatStackCoversScoreChanged
hiromaily/go-crypto-wallet.cursor/rules/typescript.mdc · 126Cursor rulesgobun+5setupbuildtestlint-format+6100/1003 days ago
TechSquidTV/Hermes.cursor/rules/10-hermes-api.mdc · 45Cursor rulestypescriptpytest+15testlint-formatstylearch+5100/1003 days ago
markstev/mark-starter.cursor/rules/frontend.mdc · 0Cursor rulestypescriptturborepo+14setuptestlint-formatstyle+699/1003 days ago
Allymahmoud/case-intake-platform.cursor/rules/frontend.mdc · 0Cursor rulestypescriptturborepo+13setuptestlint-formatstyle+799/1003 days ago
dodgecfr/combatfilms-webapp.cursor/rules/frontend.mdc · 0Cursor rulestypescriptturborepo+15setuptestlint-formatstyle+799/1003 days ago
deifos/clipmira-subtitles.cursor/rules/frontend.mdc · 1Cursor rulestypescriptnextjs+5setuptestlint-formatstyle+799/1003 days ago
langflow-ai/langflow.cursor/rules/docs_development.mdc · 153kCursor rulespythonnode+16setupbuildtestlint-format+797/1003 days ago
TechSquidTV/Hermes.cursor/rules/20-hermes-api-tests.mdc · 45Cursor rulestypescriptpytest+15teststyletesting-strategysecurity+397/1003 days ago
RuleStack

Built by

Kynth Studio

Directory

Configs
Stacks
Compare formats
Diff two configs
Best AGENTS.md examples

Formats

AGENTS.md
CLAUDE.md
Cursor rules
Copilot instructions

Reference

Read API
Corpus health
Privacy Policy
Terms

RuleStack

RuleStack

Built by

Kynth Studio

Directory

Configs
Stacks
Compare formats
Diff two configs
Best AGENTS.md examples

Formats

AGENTS.md
CLAUDE.md
Cursor rules
Copilot instructions

Reference

Read API
Corpus health
Privacy Policy
Terms

RuleStack

RuleStack

Built by

Kynth Studio

Directory

Configs
Stacks
Compare formats
Diff two configs
Best AGENTS.md examples

Formats

AGENTS.md
CLAUDE.md
Cursor rules
Copilot instructions

Reference

Read API
Corpus health
Privacy Policy
Terms

RuleStack