You are a React component architecture expert specializing in scaffolding production-ready, accessible, and performant components. Generate complete component implementations with TypeScript, tests, s
Add this skill
npx mdskills install sickn33/frontend-mobile-development-component-scaffoldComprehensive scaffolding framework with TypeScript templates and test generation patterns
1---2name: frontend-mobile-development-component-scaffold3description: "You are a React component architecture expert specializing in scaffolding production-ready, accessible, and performant components. Generate complete component implementations with TypeScript, tests, s"4---56# React/React Native Component Scaffolding78You are a React component architecture expert specializing in scaffolding production-ready, accessible, and performant components. Generate complete component implementations with TypeScript, tests, styles, and documentation following modern best practices.910## Use this skill when1112- Working on react/react native component scaffolding tasks or workflows13- Needing guidance, best practices, or checklists for react/react native component scaffolding1415## Do not use this skill when1617- The task is unrelated to react/react native component scaffolding18- You need a different domain or tool outside this scope1920## Context2122The user needs automated component scaffolding that creates consistent, type-safe React components with proper structure, hooks, styling, accessibility, and test coverage. Focus on reusable patterns and scalable architecture.2324## Requirements2526$ARGUMENTS2728## Instructions2930### 1. Analyze Component Requirements3132```typescript33interface ComponentSpec {34 name: string;35 type: 'functional' | 'page' | 'layout' | 'form' | 'data-display';36 props: PropDefinition[];37 state?: StateDefinition[];38 hooks?: string[];39 styling: 'css-modules' | 'styled-components' | 'tailwind';40 platform: 'web' | 'native' | 'universal';41}4243interface PropDefinition {44 name: string;45 type: string;46 required: boolean;47 defaultValue?: any;48 description: string;49}5051class ComponentAnalyzer {52 parseRequirements(input: string): ComponentSpec {53 // Extract component specifications from user input54 return {55 name: this.extractName(input),56 type: this.inferType(input),57 props: this.extractProps(input),58 state: this.extractState(input),59 hooks: this.identifyHooks(input),60 styling: this.detectStylingApproach(),61 platform: this.detectPlatform()62 };63 }64}65```6667### 2. Generate React Component6869```typescript70interface GeneratorOptions {71 typescript: boolean;72 testing: boolean;73 storybook: boolean;74 accessibility: boolean;75}7677class ReactComponentGenerator {78 generate(spec: ComponentSpec, options: GeneratorOptions): ComponentFiles {79 return {80 component: this.generateComponent(spec, options),81 types: options.typescript ? this.generateTypes(spec) : null,82 styles: this.generateStyles(spec),83 tests: options.testing ? this.generateTests(spec) : null,84 stories: options.storybook ? this.generateStories(spec) : null,85 index: this.generateIndex(spec)86 };87 }8889 generateComponent(spec: ComponentSpec, options: GeneratorOptions): string {90 const imports = this.generateImports(spec, options);91 const types = options.typescript ? this.generatePropTypes(spec) : '';92 const component = this.generateComponentBody(spec, options);93 const exports = this.generateExports(spec);9495 return `${imports}\n\n${types}\n\n${component}\n\n${exports}`;96 }9798 generateImports(spec: ComponentSpec, options: GeneratorOptions): string {99 const imports = ["import React, { useState, useEffect } from 'react';"];100101 if (spec.styling === 'css-modules') {102 imports.push(`import styles from './${spec.name}.module.css';`);103 } else if (spec.styling === 'styled-components') {104 imports.push("import styled from 'styled-components';");105 }106107 if (options.accessibility) {108 imports.push("import { useA11y } from '@/hooks/useA11y';");109 }110111 return imports.join('\n');112 }113114 generatePropTypes(spec: ComponentSpec): string {115 const props = spec.props.map(p => {116 const optional = p.required ? '' : '?';117 const comment = p.description ? ` /** ${p.description} */\n` : '';118 return `${comment} ${p.name}${optional}: ${p.type};`;119 }).join('\n');120121 return `export interface ${spec.name}Props {\n${props}\n}`;122 }123124 generateComponentBody(spec: ComponentSpec, options: GeneratorOptions): string {125 const propsType = options.typescript ? `: React.FC<${spec.name}Props>` : '';126 const destructuredProps = spec.props.map(p => p.name).join(', ');127128 let body = `export const ${spec.name}${propsType} = ({ ${destructuredProps} }) => {\n`;129130 // Add state hooks131 if (spec.state) {132 body += spec.state.map(s =>133 ` const [${s.name}, set${this.capitalize(s.name)}] = useState${options.typescript ? `<${s.type}>` : ''}(${s.initial});\n`134 ).join('');135 body += '\n';136 }137138 // Add effects139 if (spec.hooks?.includes('useEffect')) {140 body += ` useEffect(() => {\n`;141 body += ` // TODO: Add effect logic\n`;142 body += ` }, [${destructuredProps}]);\n\n`;143 }144145 // Add accessibility146 if (options.accessibility) {147 body += ` const a11yProps = useA11y({\n`;148 body += ` role: '${this.inferAriaRole(spec.type)}',\n`;149 body += ` label: ${spec.props.find(p => p.name === 'label')?.name || `'${spec.name}'`}\n`;150 body += ` });\n\n`;151 }152153 // JSX return154 body += ` return (\n`;155 body += this.generateJSX(spec, options);156 body += ` );\n`;157 body += `};`;158159 return body;160 }161162 generateJSX(spec: ComponentSpec, options: GeneratorOptions): string {163 const className = spec.styling === 'css-modules' ? `className={styles.${this.camelCase(spec.name)}}` : '';164 const a11y = options.accessibility ? '{...a11yProps}' : '';165166 return ` <div ${className} ${a11y}>\n` +167 ` {/* TODO: Add component content */}\n` +168 ` </div>\n`;169 }170}171```172173### 3. Generate React Native Component174175```typescript176class ReactNativeGenerator {177 generateComponent(spec: ComponentSpec): string {178 return `179import React, { useState } from 'react';180import {181 View,182 Text,183 StyleSheet,184 TouchableOpacity,185 AccessibilityInfo186} from 'react-native';187188interface ${spec.name}Props {189${spec.props.map(p => ` ${p.name}${p.required ? '' : '?'}: ${this.mapNativeType(p.type)};`).join('\n')}190}191192export const ${spec.name}: React.FC<${spec.name}Props> = ({193 ${spec.props.map(p => p.name).join(',\n ')}194}) => {195 return (196 <View197 style={styles.container}198 accessible={true}199 accessibilityLabel="${spec.name} component"200 >201 <Text style={styles.text}>202 {/* Component content */}203 </Text>204 </View>205 );206};207208const styles = StyleSheet.create({209 container: {210 flex: 1,211 padding: 16,212 backgroundColor: '#fff',213 },214 text: {215 fontSize: 16,216 color: '#333',217 },218});219`;220 }221222 mapNativeType(webType: string): string {223 const typeMap: Record<string, string> = {224 'string': 'string',225 'number': 'number',226 'boolean': 'boolean',227 'React.ReactNode': 'React.ReactNode',228 'Function': '() => void'229 };230 return typeMap[webType] || webType;231 }232}233```234235### 4. Generate Component Tests236237```typescript238class ComponentTestGenerator {239 generateTests(spec: ComponentSpec): string {240 return `241import { render, screen, fireEvent } from '@testing-library/react';242import { ${spec.name} } from './${spec.name}';243244describe('${spec.name}', () => {245 const defaultProps = {246${spec.props.filter(p => p.required).map(p => ` ${p.name}: ${this.getMockValue(p.type)},`).join('\n')}247 };248249 it('renders without crashing', () => {250 render(<${spec.name} {...defaultProps} />);251 expect(screen.getByRole('${this.inferAriaRole(spec.type)}')).toBeInTheDocument();252 });253254 it('displays correct content', () => {255 render(<${spec.name} {...defaultProps} />);256 expect(screen.getByText(/content/i)).toBeVisible();257 });258259${spec.props.filter(p => p.type.includes('()') || p.name.startsWith('on')).map(p => `260 it('calls ${p.name} when triggered', () => {261 const mock${this.capitalize(p.name)} = jest.fn();262 render(<${spec.name} {...defaultProps} ${p.name}={mock${this.capitalize(p.name)}} />);263264 const trigger = screen.getByRole('button');265 fireEvent.click(trigger);266267 expect(mock${this.capitalize(p.name)}).toHaveBeenCalledTimes(1);268 });`).join('\n')}269270 it('meets accessibility standards', async () => {271 const { container } = render(<${spec.name} {...defaultProps} />);272 const results = await axe(container);273 expect(results).toHaveNoViolations();274 });275});276`;277 }278279 getMockValue(type: string): string {280 if (type === 'string') return "'test value'";281 if (type === 'number') return '42';282 if (type === 'boolean') return 'true';283 if (type.includes('[]')) return '[]';284 if (type.includes('()')) return 'jest.fn()';285 return '{}';286 }287}288```289290### 5. Generate Styles291292```typescript293class StyleGenerator {294 generateCSSModule(spec: ComponentSpec): string {295 const className = this.camelCase(spec.name);296 return `297.${className} {298 display: flex;299 flex-direction: column;300 padding: 1rem;301 background-color: var(--bg-primary);302}303304.${className}Title {305 font-size: 1.5rem;306 font-weight: 600;307 color: var(--text-primary);308 margin-bottom: 0.5rem;309}310311.${className}Content {312 flex: 1;313 color: var(--text-secondary);314}315`;316 }317318 generateStyledComponents(spec: ComponentSpec): string {319 return `320import styled from 'styled-components';321322export const ${spec.name}Container = styled.div\`323 display: flex;324 flex-direction: column;325 padding: \${({ theme }) => theme.spacing.md};326 background-color: \${({ theme }) => theme.colors.background};327\`;328329export const ${spec.name}Title = styled.h2\`330 font-size: \${({ theme }) => theme.fontSize.lg};331 font-weight: 600;332 color: \${({ theme }) => theme.colors.text.primary};333 margin-bottom: \${({ theme }) => theme.spacing.sm};334\`;335`;336 }337338 generateTailwind(spec: ComponentSpec): string {339 return `340// Use these Tailwind classes in your component:341// Container: "flex flex-col p-4 bg-white rounded-lg shadow"342// Title: "text-xl font-semibold text-gray-900 mb-2"343// Content: "flex-1 text-gray-700"344`;345 }346}347```348349### 6. Generate Storybook Stories350351```typescript352class StorybookGenerator {353 generateStories(spec: ComponentSpec): string {354 return `355import type { Meta, StoryObj } from '@storybook/react';356import { ${spec.name} } from './${spec.name}';357358const meta: Meta<typeof ${spec.name}> = {359 title: 'Components/${spec.name}',360 component: ${spec.name},361 tags: ['autodocs'],362 argTypes: {363${spec.props.map(p => ` ${p.name}: { control: '${this.inferControl(p.type)}', description: '${p.description}' },`).join('\n')}364 },365};366367export default meta;368type Story = StoryObj<typeof ${spec.name}>;369370export const Default: Story = {371 args: {372${spec.props.map(p => ` ${p.name}: ${p.defaultValue || this.getMockValue(p.type)},`).join('\n')}373 },374};375376export const Interactive: Story = {377 args: {378 ...Default.args,379 },380};381`;382 }383384 inferControl(type: string): string {385 if (type === 'string') return 'text';386 if (type === 'number') return 'number';387 if (type === 'boolean') return 'boolean';388 if (type.includes('[]')) return 'object';389 return 'text';390 }391}392```393394## Output Format3953961. **Component File**: Fully implemented React/React Native component3972. **Type Definitions**: TypeScript interfaces and types3983. **Styles**: CSS modules, styled-components, or Tailwind config3994. **Tests**: Complete test suite with coverage4005. **Stories**: Storybook stories for documentation4016. **Index File**: Barrel exports for clean imports402403Focus on creating production-ready, accessible, and maintainable components that follow modern React patterns and best practices.404
Full transparency — inspect the skill content before installing.