Files
gh-jeremylongshore-claude-c…/commands/component-generator.md
2025-11-30 08:20:34 +08:00

6.7 KiB
Raw Permalink Blame History

description, shortcut, category, difficulty, estimated_time
description shortcut category difficulty estimated_time
Generate React components from descriptions with TypeScript and tests cg frontend beginner 2-5 minutes

Component Generator

Generates production-ready React components from natural language descriptions, including TypeScript types, styling, and tests.

What This Command Does

Component Generation:

  • Creates React component with TypeScript
  • Generates prop types and interfaces
  • Adds basic styling (CSS modules or Tailwind)
  • Creates test file (React Testing Library)
  • Includes JSDoc comments
  • Follows React best practices

Output: Complete component with types, styles, and tests

Time: 2-5 minutes


Usage

# Generate component from description
/component-generator "Create a Card component with image, title, description, and action button"

# Shortcut
/cg "Button component with loading state and icon support"

# Specify framework/style
/cg "Modal dialog with animations" --style tailwind --test vitest

# Generate with directory
/cg "UserProfile component" --output src/components/UserProfile

Example Output

Input:

/cg "Create a Button component with variants (primary, secondary, ghost), sizes (sm, md, lg), loading state, and icon support"

Generated Files:

Button.tsx:

import { ButtonHTMLAttributes, ReactNode } from 'react'
import styles from './Button.module.css'

export interface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
  /** Button visual variant */
  variant?: 'primary' | 'secondary' | 'ghost'
  /** Button size */
  size?: 'sm' | 'md' | 'lg'
  /** Show loading spinner */
  loading?: boolean
  /** Icon to display before text */
  icon?: ReactNode
  /** Button content */
  children: ReactNode
}

/**
 * Button component with multiple variants and sizes
 *
 * @example
 * ```tsx
 * <Button variant="primary" size="md" onClick={handleClick}>
 *   Click me
 * </Button>
 * ```
 */
export function Button({
  variant = 'primary',
  size = 'md',
  loading = false,
  icon,
  children,
  disabled,
  className = '',
  ...props
}: ButtonProps) {
  return (
    <button
      className={`${styles.button} ${styles[variant]} ${styles[size]} ${className}`}
      disabled={disabled || loading}
      aria-busy={loading}
      {...props}
    >
      {loading ? (
        <span className={styles.spinner} aria-label="Loading" />
      ) : (
        <>
          {icon && <span className={styles.icon}>{icon}</span>}
          {children}
        </>
      )}
    </button>
  )
}

Button.module.css:

.button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  border: none;
  border-radius: 0.375rem;
  font-weight: 500;
  cursor: pointer;
  transition: all 0.2s;
}

.button:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

/* Variants */
.primary {
  background: #3b82f6;
  color: white;
}

.primary:hover:not(:disabled) {
  background: #2563eb;
}

.secondary {
  background: #e5e7eb;
  color: #374151;
}

.ghost {
  background: transparent;
  color: #3b82f6;
}

/* Sizes */
.sm {
  padding: 0.5rem 1rem;
  font-size: 0.875rem;
}

.md {
  padding: 0.75rem 1.5rem;
  font-size: 1rem;
}

.lg {
  padding: 1rem 2rem;
  font-size: 1.125rem;
}

.spinner {
  display: inline-block;
  width: 1em;
  height: 1em;
  border: 2px solid currentColor;
  border-right-color: transparent;
  border-radius: 50%;
  animation: spin 0.6s linear infinite;
}

@keyframes spin {
  to { transform: rotate(360deg); }
}

Button.test.tsx:

import { render, screen, fireEvent } from '@testing-library/react'
import { Button } from './Button'

describe('Button', () => {
  it('renders button with text', () => {
    render(<Button>Click me</Button>)
    expect(screen.getByRole('button')).toHaveTextContent('Click me')
  })

  it('handles click events', () => {
    const handleClick = jest.fn()
    render(<Button onClick={handleClick}>Click</Button>)

    fireEvent.click(screen.getByRole('button'))
    expect(handleClick).toHaveBeenCalledTimes(1)
  })

  it('shows loading state', () => {
    render(<Button loading>Submit</Button>)

    const button = screen.getByRole('button')
    expect(button).toHaveAttribute('aria-busy', 'true')
    expect(button).toBeDisabled()
  })

  it('disables button when disabled prop is true', () => {
    render(<Button disabled>Disabled</Button>)
    expect(screen.getByRole('button')).toBeDisabled()
  })

  it('renders with icon', () => {
    const icon = <span data-testid="icon"></span>
    render(<Button icon={icon}>With Icon</Button>)

    expect(screen.getByTestId('icon')).toBeInTheDocument()
  })

  it('applies correct variant classes', () => {
    const { rerender } = render(<Button variant="primary">Primary</Button>)
    expect(screen.getByRole('button')).toHaveClass('primary')

    rerender(<Button variant="secondary">Secondary</Button>)
    expect(screen.getByRole('button')).toHaveClass('secondary')
  })
})

Component Templates

Common Components Generated

1. Card Component:

<Card
  image="/product.jpg"
  title="Product Name"
  description="Product description"
  action={<Button>Buy Now</Button>}
/>

2. Modal Component:

<Modal
  isOpen={isOpen}
  onClose={handleClose}
  title="Confirm Action"
>
  <p>Are you sure?</p>
</Modal>

3. Form Field Component:

<FormField
  label="Email"
  type="email"
  error={errors.email}
  required
/>

4. Dropdown Component:

<Dropdown
  items={options}
  value={selected}
  onChange={handleChange}
  placeholder="Select option"
/>

Features

Accessibility Built-In

  • Semantic HTML elements
  • ARIA attributes where needed
  • Keyboard navigation support
  • Focus management
  • Screen reader announcements

TypeScript Support

  • Full type definitions
  • Prop validation
  • IntelliSense support
  • Generic types where appropriate

Testing Included

  • Unit tests with React Testing Library
  • Accessibility tests
  • User interaction tests
  • Edge case coverage

Styling Options

  • CSS Modules (default)
  • Tailwind CSS
  • Styled Components
  • Emotion
  • Plain CSS

Best Practices Applied

Component Structure:

  • Single responsibility
  • Composable design
  • Prop drilling avoided
  • Performance optimized (React.memo where beneficial)

Code Quality:

  • ESLint compliant
  • Prettier formatted
  • TypeScript strict mode
  • JSDoc comments

Testing:

  • 80%+ code coverage
  • User-centric tests (not implementation details)
  • Accessibility assertions
  • Happy path + edge cases

  • /css-utility-generator - Generate utility CSS classes
  • React Specialist (agent) - React architecture guidance
  • UI/UX Expert (agent) - Design review

Generate components in seconds. Ship features faster.