Claude-skill-registry add-component

Create a React component with TypeScript and optional tests

install
source · Clone the upstream repo
git clone https://github.com/majiayu000/claude-skill-registry
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/majiayu000/claude-skill-registry "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/data/add-component" ~/.claude/skills/majiayu000-claude-skill-registry-add-component && rm -rf "$T"
manifest: skills/data/add-component/SKILL.md
source content

Add Component: $ARGUMENTS

Create a new React component with proper TypeScript types.

Process

1. Determine Component Type

Based on the name and description:

  • UI Component: Presentational, receives props
  • Container: Manages state, fetches data
  • Layout: Wraps other components
  • Form: Handles user input

2. Create Component File

Location:

components/[ComponentName].tsx

'use client'; // if using hooks or browser APIs

import { useState } from 'react';

interface ComponentNameProps {
  // Define props
  title: string;
  onAction?: () => void;
}

export default function ComponentName({ title, onAction }: ComponentNameProps) {
  return (
    <div data-testid="component-name" className="p-4">
      <h2>{title}</h2>
      {onAction && (
        <button onClick={onAction} data-testid="action-button">
          Action
        </button>
      )}
    </div>
  );
}

3. Add to Exports (if using barrel exports)

// components/index.ts
export { default as ComponentName } from './ComponentName';

4. Create Test File (optional but recommended)

// components/ComponentName.test.tsx
import { render, screen, fireEvent } from '@testing-library/react';
import ComponentName from './ComponentName';

describe('ComponentName', () => {
  test('renders with title', () => {
    render(<ComponentName title="Test" />);
    expect(screen.getByText('Test')).toBeInTheDocument();
  });

  test('calls onAction when button clicked', () => {
    const handleAction = jest.fn();
    render(<ComponentName title="Test" onAction={handleAction} />);
    fireEvent.click(screen.getByTestId('action-button'));
    expect(handleAction).toHaveBeenCalled();
  });
});

5. Validate

npm run build
npm run lint

Component Patterns

Controlled input:

interface InputProps {
  value: string;
  onChange: (value: string) => void;
}

With children:

interface WrapperProps {
  children: React.ReactNode;
}

With ref:

const Component = forwardRef<HTMLDivElement, Props>((props, ref) => {
  return <div ref={ref} {...props} />;
});

With default props:

interface Props {
  size?: 'sm' | 'md' | 'lg';
}

function Component({ size = 'md' }: Props) { ... }