Generate optimized React components for Next.js with TypeScript and best practices
npx claude-code-templates@latest --skill β’β’β’β’β’β’β’β’β’β’β’β’β’β’β’β’β’β’β’β’Unlock this skill to run and inspect the interactive installation sequence.
Component Name: $ARGUMENTS
Based on arguments and context, determine component type:
--client or default for interactive components)--server or default for Next.js 13+)--page)--layout)Generate comprehensive component structure:
components/[ComponentName]/ βββ index.ts # Barrel export βββ [ComponentName].tsx # Main component βββ [ComponentName].module.css # Component styles βββ [ComponentName].test.tsx # Unit tests βββ [ComponentName].stories.tsx # Storybook story (if detected) βββ types.ts # TypeScript types
import { FC } from 'react';
import styles from './ComponentName.module.css';
interface ComponentNameProps {
/**
* Component description
*/
children?: React.ReactNode;
/**
* Additional CSS classes
*/
className?: string;
}
/**
* ComponentName - Server Component
*
* @description Brief description of component purpose
* @example
* <ComponentName>Content</ComponentName>
*/
export const ComponentName: FC<ComponentNameProps> = ({
children,
className = '',
...props
}) => {
return (
<div className={`${styles.container} ${className}`} {...props}>
{children}
</div>
);
};
export default ComponentName;'use client';
import { FC, useState, useEffect } from 'react';
import styles from './ComponentName.module.css';
interface ComponentNameProps {
/**
* Component description
*/
children?: React.ReactNode;
/**
* Click event handler
*/
onClick?: () => void;
/**
* Additional CSS classes
*/
className?: string;
}
/**
* ComponentName - Client Component
*
* @description Interactive component with client-side functionality
* @example
* <ComponentName onClick={() => console.log('clicked')}>
* Content
* </ComponentName>
*/
export const ComponentName: FC<ComponentNameProps> = ({
children,
onClick,
className = '',
...props
}) => {
const [isActive, setIsActive] = useState(false);
const handleClick = () => {
setIsActive(!isActive);
onClick?.();
};
return (
<button
className={`${styles.button} ${isActive ? styles.active : ''} ${className}`}
onClick={handleClick}
{...props}
>
{children}
</button>
);
};
export default ComponentName;import { Metadata } from 'next';
import ComponentName from '@/components/ComponentName';
export const metadata: Metadata = {
title: 'Page Title',
description: 'Page description',
};
interface PageProps {
params: { id: string };
searchParams: { [key: string]: string | string[] | undefined };
}
export default function Page({ params, searchParams }: PageProps) {
return (
<main>
<h1>Page Title</h1>
<ComponentName />
</main>
);
}import { FC } from 'react';
import styles from './Layout.module.css';
interface LayoutProps {
children: React.ReactNode;
/**
* Page title
*/
title?: string;
}
/**
* Layout - Shared layout component
*
* @description Provides consistent layout structure across pages
*/
export const Layout: FC<LayoutProps> = ({
children,
title,
}) => {
return (
<div className={styles.layout}>
<header className={styles.header}>
{title && <h1 className={styles.title}>{title}</h1>}
</header>
<main className={styles.main}>
{children}
</main>
<footer className={styles.footer}>
<p>Β© 2024 Your App</p>
</footer>
</div>
);
};
export default Layout;/* ComponentName.module.css */
.container {
display: flex;
flex-direction: column;
padding: 1rem;
border-radius: 8px;
border: 1px solid #e2e8f0;
background-color: #ffffff;
}
.button {
display: inline-flex;
align-items: center;
justify-content: center;
padding: 0.5rem 1rem;
border-radius: 6px;
border: 1px solid transparent;
background-color: #3b82f6;
color: white;
font-weight: 500;
cursor: pointer;
transition: all 0.2s;
}
.button:hover {
background-color: #2563eb;
}
.button:focus {
outline: 2px solid #3b82f6;
outline-offset: 2px;
}
.button.active {
background-color: #1d4ed8;
}
/* Responsive design */
@media (max-width: 768px) {
.container {
padding: 0.75rem;
}
.button {
padding: 0.75rem 1rem;
}
}/* Layout.module.css */
.layout {
min-height: 100vh;
display: grid;
grid-template-rows: auto 1fr auto;
}
.header {
padding: 1rem 2rem;
background-color: #f8fafc;
border-bottom: 1px solid #e2e8f0;
}
.title {
margin: 0;
font-size: 1.5rem;
font-weight: 600;
color: #1e293b;
}
.main {
padding: 2rem;
max-width: 1200px;
margin: 0 auto;
width: 100%;
}
.footer {
padding: 1rem 2rem;
background-color: #f1f5f9;
border-top: 1px solid #e2e8f0;
text-align: center;
color: #64748b;
}// types.ts
export interface BaseComponentProps {
children?: React.ReactNode;
className?: string;
'data-testid'?: string;
}
export interface ButtonProps extends BaseComponentProps {
variant?: 'primary' | 'secondary' | 'outline';
size?: 'sm' | 'md' | 'lg';
disabled?: boolean;
loading?: boolean;
onClick?: () => void;
}
export interface LayoutProps extends BaseComponentProps {
title?: string;
sidebar?: React.ReactNode;
breadcrumbs?: BreadcrumbItem[];
}
export interface BreadcrumbItem {
label: string;
href?: string;
current?: boolean;
}// ComponentName.test.tsx
import { render, screen, fireEvent } from '@testing-library/react';
import ComponentName from './ComponentName';
describe('ComponentName', () => {
it('renders children correctly', () => {
render(<ComponentName>Test Content</ComponentName>);
expect(screen.getByText('Test Content')).toBeInTheDocument();
});
it('applies custom className', () => {
render(<ComponentName className="custom-class">Test</ComponentName>);
const element = screen.getByText('Test');
expect(element).toHaveClass('custom-class');
});
it('handles click events', () => {
const handleClick = jest.fn();
render(<ComponentName onClick={handleClick}>Click me</ComponentName>);
const button = screen.getByText('Click me');
fireEvent.click(button);
expect(handleClick).toHaveBeenCalledTimes(1);
});
it('toggles active state on click', () => {
render(<ComponentName>Toggle</ComponentName>);
const button = screen.getByText('Toggle');
expect(button).not.toHaveClass('active');
fireEvent.click(button);
expect(button).toHaveClass('active');
fireEvent.click(button);
expect(button).not.toHaveClass('active');
});
it('is accessible', () => {
render(<ComponentName>Accessible Button</ComponentName>);
const button = screen.getByRole('button');
expect(button).toBeInTheDocument();
expect(button).toHaveAccessibleName('Accessible Button');
});
});// ComponentName.stories.tsx
import type { Meta, StoryObj } from '@storybook/react';
import ComponentName from './ComponentName';
const meta: Meta<typeof ComponentName> = {
title: 'Components/ComponentName',
component: ComponentName,
parameters: {
layout: 'centered',
docs: {
description: {
component: 'A reusable component built for Next.js applications.',
},
},
},
tags: ['autodocs'],
argTypes: {
onClick: { action: 'clicked' },
className: { control: 'text' },
},
};
export default meta;
type Story = StoryObj<typeof meta>;
export const Default: Story = {
args: {
children: 'Default Component',
},
};
export const WithCustomClass: Story = {
args: {
children: 'Custom Styled',
className: 'custom-style',
},
};
export const Interactive: Story = {
args: {
children: 'Click me',
onClick: () => alert('Component clicked!'),
},
};// index.ts
export { default } from './ComponentName';
export type { ComponentNameProps } from './ComponentName';Replace CSS modules with Tailwind classes:
export const ComponentName: FC<ComponentNameProps> = ({
children,
className = '',
}) => {
return (
<div className={`flex flex-col p-4 rounded-lg border border-slate-200 bg-white ${className}`}>
{children}
</div>
);
};Provide the complete component implementation with all specified files and features.
# Step 1: Initialize skill agent setup
npx skills add Nextjs Component Generator --install-production
python -m pip install -r requirements.txt
codex plugin install Nextjs Component Generator@latest
export API_KEY=secret_token_key_here
Unlock this skill to reveal complete step-by-step setup guides, terminal commands, configuration recipes, repository links, and interactive installation video walkthroughs.
Get instant access to complete setup guides, repository source code, and integration assets.
Generate a complete test file for a specified source file or component. Use when the user explicitly asks to write, create, or generate tests for a specific file.
Multi-framework structured analysis: surfaces hidden assumptions, generates competing solutions, stress-tests each with adversarial reasoning, and delivers confidence-calibrated recommendations
Generate comprehensive architecture documentation with diagrams, ADRs, and interactive visualization