// Generate production-ready Next.js/React components from design specifications. Use this skill when you have a design specification document and need to create React/TypeScript components with Tailwind CSS styling, Vitest tests, and Storybook documentation.
| name | nextjs-react-implementation |
| description | Generate production-ready Next.js/React components from design specifications. Use this skill when you have a design specification document and need to create React/TypeScript components with Tailwind CSS styling, Vitest tests, and Storybook documentation. |
Transform design specification documents into production-ready Next.js/React components with complete TypeScript types, Tailwind CSS styling, comprehensive tests, and Storybook documentation. This skill focuses on accurate implementation following modern React patterns and best practices.
Use this skill when:
This skill expects a design specification document created by the figma-design-analyzer skill or a similar structured specification. The specification should include:
Read and understand the design specification document:
Load the specification file:
.design.md fileIdentify key information:
Validate specification:
Plan the component implementation:
Determine component directory:
src/components/
atoms/ComponentName/
molecules/ComponentName/
organisms/ComponentName/
Plan file structure:
ComponentName/
├── index.ts # Barrel export
├── ComponentName.tsx # Component implementation
├── ComponentName.test.tsx # Vitest tests
└── ComponentName.stories.tsx # Storybook stories
Identify dependencies:
Create type-safe props based on the specification:
Read variant information from spec:
## Variants
- variant: primary | secondary | tertiary
- size: small | medium | large
Create props interface:
export interface ButtonProps {
/** Button variant style */
variant?: 'primary' | 'secondary' | 'tertiary';
/** Button size */
size?: 'small' | 'medium' | 'large';
/** Button content */
children: React.ReactNode;
/** Click handler */
onClick?: () => void;
/** Disabled state */
disabled?: boolean;
/** Additional CSS classes */
className?: string;
}
Set default props:
Use the component template to create the implementation:
Read the component template:
assets/templates/component.tsx.template
Fill in template placeholders:
{{COMPONENT_NAME}}: Component name in PascalCase{{COMPONENT_DESCRIPTION}}: Brief description from spec{{ATOMIC_CATEGORY}}: Atoms, Molecules, or Organisms{{ROOT_ELEMENT}}: Semantic HTML element{{TAILWIND_CLASSES}}: Base Tailwind classes from specImplement variant logic:
const variantClasses = {
primary: 'bg-blue-500 text-white hover:bg-blue-600',
secondary: 'bg-white text-blue-500 border-blue-500 hover:bg-blue-50',
tertiary: 'bg-transparent text-blue-500 hover:bg-blue-50'
};
const sizeClasses = {
small: 'px-4 py-2 text-sm',
medium: 'px-6 py-3 text-base',
large: 'px-8 py-4 text-lg'
};
const className = cn(
'inline-flex items-center justify-center rounded-lg font-semibold',
'transition-colors duration-200',
'disabled:opacity-50 disabled:cursor-not-allowed',
variantClasses[variant],
sizeClasses[size],
props.className
);
Handle responsive behavior:
className = cn(
'w-full md:w-auto', // Full width on mobile, auto on tablet+
'px-4 md:px-6 lg:px-8', // Responsive padding
// ... other classes
);
Implement accessibility:
<button
className={className}
disabled={disabled}
onClick={onClick}
aria-label={ariaLabel}
{...props}
>
{children}
</button>
Create comprehensive tests using the test template:
Read the test template:
assets/templates/test.tsx.template
Set up test structure:
import { describe, it, expect, vi } from 'vitest';
import { page } from '@vitest/browser/context';
import { render } from 'vitest-browser-react';
import { Button } from './Button';
describe('Button', () => {
// Test cases here
});
Follow TDD principles with Arrange-Act-Assert:
it('正しくレンダリングされること', async () => {
// Arrange
const props = { children: 'Click Me' };
// Act
await render(<Button {...props} />);
// Assert
const button = page.getByRole('button', { name: 'Click Me' });
await expect.element(button).toBeVisible();
});
Test all variants:
it.each([
{ variant: 'primary', expectedClass: 'bg-blue-500' },
{ variant: 'secondary', expectedClass: 'bg-white' },
{ variant: 'tertiary', expectedClass: 'bg-transparent' }
])('$variant バリアントが正しくレンダリングされること', async ({ variant, expectedClass }) => {
// Arrange & Act
await render(<Button variant={variant}>Button</Button>);
// Assert
const button = page.getByRole('button');
await expect.element(button).toHaveClass(expectedClass);
});
Test all states:
it('無効状態が正しく動作すること', async () => {
// Arrange
const handleClick = vi.fn();
await render(
<Button disabled onClick={handleClick}>
Disabled
</Button>
);
// Act
const button = page.getByRole('button');
await button.click();
// Assert
await expect.element(button).toBeDisabled();
expect(handleClick).not.toHaveBeenCalled();
});
Test interactions:
it('クリックイベントが動作すること', async () => {
// Arrange
const handleClick = vi.fn();
await render(<Button onClick={handleClick}>Click Me</Button>);
// Act
const button = page.getByRole('button');
await button.click();
// Assert
expect(handleClick).toHaveBeenCalledTimes(1);
});
Test accessibility:
it('キーボード操作が動作すること', async () => {
// Arrange
const handleClick = vi.fn();
await render(<Button onClick={handleClick}>Press Enter</Button>);
// Act
const button = page.getByRole('button');
await button.focus();
await page.keyboard.press('Enter');
// Assert
expect(handleClick).toHaveBeenCalled();
});
Create interactive documentation:
Read the Storybook template:
assets/templates/storybook.tsx.template
Set up story structure:
import type { Meta, StoryObj } from '@storybook/react';
import { Button } from './Button';
const meta = {
title: 'Atoms/Button',
component: Button,
parameters: {
layout: 'centered',
},
tags: ['autodocs'],
argTypes: {
variant: {
control: 'select',
options: ['primary', 'secondary', 'tertiary']
},
size: {
control: 'select',
options: ['small', 'medium', 'large']
}
}
} satisfies Meta<typeof Button>;
export default meta;
type Story = StoryObj<typeof meta>;
Create stories for each variant:
export const Primary: Story = {
args: {
variant: 'primary',
children: 'Primary Button'
}
};
export const Secondary: Story = {
args: {
variant: 'secondary',
children: 'Secondary Button'
}
};
export const Tertiary: Story = {
args: {
variant: 'tertiary',
children: 'Tertiary Button'
}
};
Create stories for different sizes:
export const Small: Story = {
args: {
size: 'small',
children: 'Small Button'
}
};
export const Medium: Story = {
args: {
size: 'medium',
children: 'Medium Button'
}
};
export const Large: Story = {
args: {
size: 'large',
children: 'Large Button'
}
};
Create stories for states:
export const Disabled: Story = {
args: {
disabled: true,
children: 'Disabled Button'
}
};
Create interactive playground:
export const Playground: Story = {
args: {
variant: 'primary',
size: 'medium',
children: 'Playground Button'
}
};
For Molecules and Organisms that use child components:
Identify child components:
Compose the component:
import { Button } from '@/components/atoms/Button';
import { Input } from '@/components/atoms/Input';
export function SearchBar({ onSearch }: SearchBarProps) {
return (
<div className="flex gap-2">
<Input placeholder="Search..." />
<Button onClick={onSearch}>Search</Button>
</div>
);
}
Pass props to children:
Add responsive styles based on the specification:
Read responsive behavior from spec:
## Responsive Behavior
- Mobile (default): flex-col gap-4 text-sm
- Tablet (md): md:flex-row md:gap-6 md:text-base
- Desktop (lg): lg:gap-8 lg:text-lg
Apply Tailwind responsive prefixes:
className = cn(
'flex flex-col gap-4 text-sm', // Mobile (default)
'md:flex-row md:gap-6 md:text-base', // Tablet
'lg:gap-8 lg:text-lg', // Desktop
// ... other classes
);
Test responsive behavior:
Create index.ts for clean imports:
export { Button } from './Button';
export type { ButtonProps } from './Button';
Final checks before completion:
Verify against specification:
Run tests:
npm run test
Run Storybook:
npm run storybook
Type check:
npm run type-check
Lint:
npm run lint
Always use Context7 MCP to get up-to-date documentation:
Resolve library IDs:
mcp__context7__resolve-library-id(libraryName: "react")
mcp__context7__resolve-library-id(libraryName: "tailwindcss")
mcp__context7__resolve-library-id(libraryName: "vitest")
Get library documentation:
mcp__context7__get-library-docs(
context7CompatibleLibraryID: "/facebook/react",
topic: "hooks"
)
Check project versions:
Type Safety:
any typeComponent Composition:
Styling:
cn() utility for conditional classesTesting:
Documentation:
Accessibility:
Performance:
This skill includes templates for code generation:
Usage: Use these templates as starting points. Fill in placeholders with values from the design specification.
Ignoring the specification:
Incomplete variant handling:
Poor test coverage:
Accessibility oversights:
Inconsistent naming:
Hardcoded values:
Input: Button.design.md specification
Steps:
src/components/atoms/Button/Button.tsx with variants (primary, secondary, tertiary) and sizes (small, medium, large)Button.test.tsx with tests for all variants, sizes, and statesButton.stories.tsx with interactive storiesindex.ts barrel exportOutput:
This skill transforms design specifications into production-ready Next.js/React components with complete testing and documentation.