--- globs: src/components/**/*.tsx --- # Component Patterns ## Component Structure ### File Organization - Place reusable components in `src/components/` - Use PascalCase for component files: `ComponentName.tsx` - Group related components in subdirectories when needed ### Component Template ```typescript import { cn } from '@/lib/utils' interface ComponentProps { className?: string children?: React.ReactNode // Other props } export function ComponentName({ className, children, ...props }: ComponentProps) { return (
{children}
) } ``` ## shadcn/ui Integration ### Using shadcn/ui Components ```typescript import { Button } from '@/components/ui/button' import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card' import { Badge } from '@/components/ui/badge' export function ProjectCard({ project }: { project: Project }) { return ( {project.title} {project.category} ) } ``` ### Extending shadcn/ui Components ```typescript // Create wrapper components for common patterns import { Button } from '@/components/ui/button' import { cn } from '@/lib/utils' interface PrimaryButtonProps extends React.ComponentProps { loading?: boolean } export function PrimaryButton({ loading, className, children, ...props }: PrimaryButtonProps) { return ( ) } ``` ## Animation Patterns ### Framer Motion Usage ```typescript import { motion } from 'framer-motion' export function AnimatedCard({ children }: { children: React.ReactNode }) { return ( {children} ) } ``` ## Component Composition ### Compound Components ```typescript // Parent component export function Accordion({ children }: { children: React.ReactNode }) { return
{children}
} // Child components export function AccordionItem({ children }: { children: React.ReactNode }) { return
{children}
} export function AccordionTrigger({ children }: { children: React.ReactNode }) { return } // Usage Title Content ``` ## Props and TypeScript ### Interface Patterns ```typescript // Use descriptive interface names interface ProjectCardProps { project: Project variant?: 'default' | 'featured' showDescription?: boolean onSelect?: (project: Project) => void } // Use React.ComponentProps for extending HTML elements interface CustomButtonProps extends React.ComponentProps<'button'> { variant?: 'primary' | 'secondary' size?: 'sm' | 'md' | 'lg' } ``` ## Styling Guidelines 1. **Tailwind First**: Use utility classes before custom CSS 2. **Conditional Classes**: Use `cn()` utility for conditional styling 3. **Responsive Design**: Mobile-first approach with responsive utilities 4. **Dark Theme**: Ensure all components work in dark mode 5. **Accessibility**: Include proper ARIA labels and semantic HTML