chihebnabil/lovable-boilerplate

A Lovable-inspired React boilerplate that brings no-code AI UI generation into clean code. Fully open, customizable, and

Stars 62 Language TypeScript Last updated 2026-07-20 Source on GitHub @chihebnabil

Actual rules from this repo

Path in source repo: .cursor/rules/components.mdc · format: mdc

---
description: Component development patterns and composition rules
globs: ["src/components/**/*.{tsx,ts}", "src/pages/**/*.{tsx,ts}"]
alwaysApply: false
---

# Component Development Rules

## Component Patterns

### GOOD Component Structure
```tsx
// Single responsibility, 20-80 lines
interface UserCardProps {
  user: User
  onEdit: (id: string) => void
  className?: string
}

export const UserCard = ({ user, onEdit, className }: UserCardProps) => {
  return (
    <Card className={cn("p-4", className)}>
      <Avatar src={user.avatar} />
      <div>
        <h3 className="font-semibold">{user.name}</h3>
        <p className="text-muted-foreground">{user.email}</p>
        <Button onClick={() => onEdit(user.id)}>Edit</Button>
      </div>
    </Card>
  )
}
```

### AVOID: Monolithic Components
```tsx
// DON'T: 300+ lines mixing concerns
const UserManagement = () => {
  // Massive component with multiple responsibilities
}
```

### Component Composition Pattern
```tsx
// Build complex UI from smaller components
const Dashboard = () => (
  <PageLayout>
    <DashboardHeader />
    <DashboardMetrics />
    <DashboardCharts />
    <DashboardActivity />
  </PageLayout>
)
```

## UI Component Rules

### shadcn/ui Components
- **NEVER** modify files in `src/components/ui/` directly
- **EXTEND** by creating wrappers in `src/components/common/`
- **COMPOSE** multiple ui components to build features

### Form Components
```tsx
// Use React Hook Form + Zod pattern
export const UserForm = ({ onSubmit, initialData }: UserFormProps) => {
  const form = useForm<UserFormData>({
    resolver: zodResolver(userSchema),
    defaultValues: initialData
  })

  return (
    <Form {...form}>
      <form onSubmit={form.handleSubmit(onSubmit)}>
        <FormField
          control={form.control}
          name="name"
          render={({ field }) => (
            <FormItem>
              <FormLabel>Name</FormLabel>
              <FormControl>
                <Input {...field} />
              </FormControl>
              <FormMessage />
            </FormItem>
          )}
        />
      </form>
    </Form>
  )
}
```

## Page Component Rules

### Pages = Composition Only
```tsx
// PERFECT: Thin orchestration layer (10-30 lines max)
const DashboardPage = () => {
  const { data: user, isLoading } = useCurrentUser()
  
  if (isLoading) return <PageSkeleton />
  
  return (
    <PageLayout>
      <DashboardHeader user={user} />
      <DashboardMetrics />
      <div className="grid grid-cols-1 lg:grid-cols-2 gap-6">
        <DashboardCharts />
        <DashboardActivity />
      </div>
    </PageLayout>
  )
}
```

### NEVER in Pages
- Business logic (extract to hooks)
- API calls (use service layer)
- Complex state management
- Inline event handlers

## Reusable Component Patterns

### Compound Components
```tsx
const DataTable = ({ children }) => (
  <div className="border rounded-lg overflow-hidden">{children}</div>
)

const DataTableHeader = ({ children }) => (
  <div className="bg-muted p-4 border-b">{children}</div>
)

// Usage
<DataTable>
  <DataTableHeader>
    <h3>Users</h3>
  </DataTableHeader>
  <DataTableBody>
    {users.map(user => <UserRow key={user.id} user={user} />)}
  </DataTableBody>
</DataTable>
```

View raw on GitHub

Why this is listed

This repository appears on Cursor Rules Live because it matches the tracker's GitHub Search criteria (cursor-rules) and was active in the recent indexing window. The tracker refreshes every 15 minutes, so the metadata above reflects the state at the most recent index pass. If the data here looks stale, the source repository may have been archived or moved out of the tracked topic; the next cron tick will reconcile.

Similar in this tracker

Explore by category