Component Scaffold Generator
Generate production-ready component skeletons with types, variants, tests, and documentation.
Core Workflow Gather requirements: Component name, framework (React/Vue), props needed Choose pattern: Determine if functional, compound, or polymorphic component Generate component: Create main component file with TypeScript types Add variants: Include common variants (size, color, state) Setup styling: Add styling approach (Tailwind, CSS Modules, styled-components) Create tests: Generate test file with basic coverage Add story: Create Storybook story with examples Document usage: Include JSDoc and usage examples Component Patterns Basic Functional Component (React) // Button.tsx import { forwardRef } from "react"; import { cn } from "@/lib/utils";
export interface ButtonProps
extends React.ButtonHTMLAttributes
/*
* Button component with multiple variants and sizes
*
* @example
* tsx
* <Button variant="primary" size="md">
* Click me
* </Button>
*
/
export const Button = forwardRef
Button.displayName = "Button";
Compound Component Pattern // Card.tsx import { createContext, useContext } from "react";
interface CardContextValue { variant: "default" | "outlined" | "elevated"; }
const CardContext = createContext
export interface CardProps extends React.HTMLAttributes
export const Card = ({
variant = "default",
className,
children,
...props
}: CardProps) => {
return (
export const CardHeader = ({
className,
...props
}: React.HTMLAttributes
);
export const CardTitle = ({
className,
...props
}: React.HTMLAttributes
);
export const CardContent = ({
className,
...props
}: React.HTMLAttributes
);
export const CardFooter = ({
className,
...props
}: React.HTMLAttributes
);
Test File Template // Button.test.tsx import { render, screen, fireEvent } from "@testing-library/react"; import { Button } from "./Button";
describe("Button", () => { it("renders children correctly", () => { render(); expect( screen.getByRole("button", { name: /click me/i }) ).toBeInTheDocument(); });
it("applies variant classes correctly", () => { const { rerender } = render(); expect(screen.getByRole("button")).toHaveClass("bg-blue-600");
rerender(<Button variant="secondary">Test</Button>);
expect(screen.getByRole("button")).toHaveClass("bg-gray-200");
});
it("handles click events", () => { const handleClick = jest.fn(); render();
fireEvent.click(screen.getByRole("button"));
expect(handleClick).toHaveBeenCalledTimes(1);
});
it("shows loading state", () => { render(); expect(screen.getByRole("button")).toBeDisabled(); expect(screen.getByRole("button")).toContainHTML("svg"); });
it("renders with icons", () => { render( ); expect(screen.getByTestId("left")).toBeInTheDocument(); });
it("forwards ref correctly", () => {
const ref = React.createRef
Storybook Story Template // Button.stories.tsx import type { Meta, StoryObj } from "@storybook/react"; import { Button } from "./Button";
const meta: Meta
export default meta;
type Story = StoryObj
export const Primary: Story = { args: { variant: "primary", children: "Button", }, };
export const Secondary: Story = { args: { variant: "secondary", children: "Button", }, };
export const WithIcons: Story = { args: { children: "With Icons", leftIcon: "←", rightIcon: "→", }, };
export const Loading: Story = { args: { children: "Loading", isLoading: true, }, };
export const Sizes: Story = { render: () => (
export const Variants: Story = { render: () => (
Vue Component Pattern
<button :class="buttonClasses" :disabled="disabled || isLoading" @click="handleClick"
<svg v-if="isLoading" class="mr-2 h-4 w-4 animate-spin" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" <circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4" /> <path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z" /> </svg> <slot />
Index File (Barrel Export) // index.ts export { Button } from "./Button"; export type { ButtonProps } from "./Button";
Usage Documentation Template
Button Component
A flexible button component with multiple variants, sizes, and states.
Installation
npm install @/components/ui/button
Usage import { Button } from "@/components/ui/button";
function App() { return ( ); }
Props Prop Type Default Description variant 'primary' | 'secondary' | 'ghost' | 'destructive' 'primary' Visual style variant size 'sm' | 'md' | 'lg' 'md' Button size isLoading boolean false Shows loading spinner leftIcon ReactNode - Icon before text rightIcon ReactNode - Icon after text disabled boolean false Disables the button Examples With Icons }>Back
Loading State
Destructive Action
Accessibility Keyboard navigable ARIA attributes included Focus visible styling Disabled state properly handled
Component Structure Template
ComponentName/ ├── ComponentName.tsx # Main component ├── ComponentName.test.tsx # Tests ├── ComponentName.stories.tsx # Storybook ├── types.ts # TypeScript types (if complex) ├── styles.module.css # CSS Modules (if used) └── index.ts # Barrel export
Common Component Types
UI Primitives
- Button, Input, Select, Checkbox, Radio
- Typography (Text, Heading, Label)
- Icons, Avatar, Badge
Layout Components
- Container, Stack, Grid, Flex
- Card, Panel, Section
- Divider, Spacer
Data Display
- Table, List, DataGrid
- Tooltip, Popover, Dropdown
- Tabs, Accordion, Collapse
Feedback
- Alert, Toast, Modal
- Progress, Spinner, Skeleton
- EmptyState, ErrorBoundary
Forms
- FormField, FormGroup, FormLabel
- FileUpload, DatePicker, RangePicker
- SearchInput, TagInput
Best Practices
- Forward refs: Use
forwardReffor DOM access - Type props properly: Extend native HTML element props
- Use composition: Compound components when appropriate
- Accessibility first: ARIA attributes, keyboard nav
- Variants system: Size, color, state variants
- Loading states: Handle async operations
- Error states: Validate and show errors
- Test coverage: At least 80% coverage
- Document usage: JSDoc and README examples
- Export types: Make TypeScript types available
Styling Approaches
Tailwind CSS (Recommended)
- Use
cn()utility for conditional classes - Define variants with object syntax
- Responsive utilities built-in
CSS Modules
- Scoped styles by default
- Type-safe with TypeScript
- Better for complex animations
Styled Components
- CSS-in-JS with props
- Dynamic theming support
- Runtime styling
Output Checklist
Every generated component should include:
- [ ] Main component file with TypeScript types
- [ ] Prop interface with JSDoc comments
- [ ] Multiple variants (size, color, state)
- [ ] Accessibility attributes
- [ ] Test file with key scenarios
- [ ] Storybook story with examples
- [ ] Barrel export (index.ts)
- [ ] Usage documentation
- [ ] Error handling
- [ ] Loading states (if applicable)