Files
ragusaitweb/AGENTS.md
Melvin Ragusa ad5ea4a3fe add: AGENTS.md
2026-01-30 05:24:08 +01:00

5.0 KiB

AGENTS.md - Coding Guidelines for RagusaIT Web

Build Commands

# Development server (port 3000)
npm run dev

# Production build
npm run build

# Preview production build
npm run preview

Test Commands

# Run all tests
npx vitest

# Run tests in watch mode
npx vitest --watch

# Run tests with coverage
npx vitest --coverage

# Run a single test file
npx vitest src/components/ui/__tests__/Button.test.tsx

# Run tests matching a pattern
npx vitest --grep "Button"

# Run specific test by name
npx vitest -t "passes aria-label to the button element"

Code Style Guidelines

TypeScript

  • Use strict TypeScript configuration
  • Always define explicit return types for functions
  • Use type for type definitions, interface for object shapes that may be extended
  • Avoid any - use unknown when type is uncertain

Imports (Order)

  1. React imports
  2. Third-party libraries (alphabetical)
  3. Absolute imports from project (@/components, @/utils)
  4. Relative imports
  5. CSS/SCSS imports last
import { useState, useEffect } from 'react';
import { motion } from 'motion/react';
import { Link } from 'react-router-dom';
import { useTranslation } from '../../i18n';
import { debounce } from '../../utils/debounce';
import styles from './Navbar.module.css';

Component Structure

  • Use named exports for all components
  • Props interface should be named [ComponentName]Props
  • Place props interface immediately before component
  • Use CSS Modules for styling (.module.css)
  • Destructure props in function signature with defaults
interface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
  variant?: 'primary' | 'secondary' | 'outline';
  size?: 'sm' | 'md' | 'lg';
  isLoading?: boolean;
}

export function Button({
  variant = 'primary',
  size = 'md',
  isLoading = false,
  children,
  ...props
}: ButtonProps) {
  // Implementation
}

Naming Conventions

  • Components: PascalCase (e.g., Navbar, Button)
  • Hooks: camelCase with use prefix (e.g., useRateLimit, useTypingEffect)
  • Utilities: camelCase (e.g., debounce, formatDate)
  • Types/Interfaces: PascalCase (e.g., ButtonProps, Translations)
  • Constants: UPPER_SNAKE_CASE for module-level constants
  • Files: Match default export name (e.g., Navbar.tsx exports Navbar)

Error Handling

  • Use try-catch for async operations
  • Provide meaningful error messages
  • Use early returns to avoid nested conditionals
  • Clean up resources (timers, event listeners) in useEffect cleanup
useEffect(() => {
  const handleScroll = () => {
    if (!ticking) {
      window.requestAnimationFrame(() => {
        setIsScrolled(window.scrollY > 20);
        ticking = false;
      });
      ticking = true;
    }
  };
  window.addEventListener('scroll', handleScroll, { passive: true });
  return () => window.removeEventListener('scroll', handleScroll);
}, []);

Testing

  • Add // @vitest-environment jsdom at top of test files
  • Use describe and it blocks with descriptive names
  • Clean up after each test with cleanup() from testing-library
  • Mock external dependencies appropriately
  • Test behavior, not implementation
// @vitest-environment jsdom
import { render, screen, cleanup } from '@testing-library/react';
import { describe, it, expect, afterEach } from 'vitest';

describe('Button', () => {
  afterEach(() => {
    cleanup();
  });

  it('renders with correct aria-label', () => {
    render(<Button aria-label="Submit">Click</Button>);
    expect(screen.getByRole('button', { name: /submit/i })).toBeTruthy();
  });
});

Performance

  • Use React.lazy() for code splitting on routes
  • Memoize expensive calculations with useMemo
  • Use requestAnimationFrame for scroll/resize handlers
  • Debounce expensive operations (use debounce utility)
  • Add will-change CSS sparingly for GPU acceleration

Accessibility

  • Always include meaningful aria-label for interactive elements
  • Use semantic HTML elements (<header>, <nav>, <main>)
  • Ensure keyboard navigation works
  • Test with screen readers

Project Structure

src/
├── components/
│   ├── effects/       # Visual effects (WebGL, animations)
│   ├── layout/        # Layout components (Navbar, Footer)
│   ├── sections/      # Page sections (Hero, Services)
│   └── ui/            # Reusable UI components (Button, Input)
├── hooks/             # Custom React hooks
├── i18n/              # Internationalization (de.ts, en.ts)
├── pages/             # Route components
├── styles/            # Global styles
└── utils/             # Utility functions

State Management

  • Use React Context for global state (e.g., i18n)
  • Prefer local state when possible
  • Use useRef for DOM references and mutable values
  • Store user preferences in localStorage with proper keys

Comments

  • Use JSDoc for exported functions
  • Explain "why" not "what" in comments
  • Keep comments concise and meaningful