1# Component Structure 2 3All components follow a consistent 4-file system. 4 5## File Structure 6 7``` 8/ComponentName/ 9├── ComponentName.tsx # Component implementation 10├── ComponentName.types.ts # TypeScript interfaces 11├── ComponentName.styles.ts # Tailwind class strings 12└── ComponentName.constants.ts # Hardcoded values, configs 13``` 14 15**Simple components** may skip `.constants.ts` if they have no hardcoded values. 16 17## Quick Reference 18 19### ComponentName.tsx 20Component logic and JSX. Import from sibling files. 21 22```typescript 23import * as styles from './Button.styles'; 24import { DEFAULT_VARIANT } from './Button.constants'; 25import { ButtonProps } from './Button.types'; 26 27export const Button: React.FC<ButtonProps> = ({ 28 variant = DEFAULT_VARIANT, 29 children 30}) => ( 31 <button className={styles.getButtonStyles(variant)}> 32 {children} 33 </button> 34); 35``` 36 37### ComponentName.types.ts 38All TypeScript interfaces and types. 39 40```typescript 41export interface ButtonProps { 42 variant?: 'primary' | 'secondary'; 43 children: React.ReactNode; 44} 45``` 46 47### ComponentName.styles.ts 48Tailwind class strings. Use `cn()` for dynamic styles. 49 50```typescript 51import { cn } from '@/lib/utils'; 52 53export const button = 'px-4 py-2 rounded font-medium'; 54 55export const getButtonStyles = (variant: string) => 56 cn(button, variant === 'primary' ? 'bg-blue-600' : 'bg-gray-200'); 57``` 58 59### ComponentName.constants.ts 60Extract hardcoded values here. 61 62```typescript 63export const DEFAULT_VARIANT = 'primary' as const; 64 65export const SOCIAL_LINKS = [ 66 { href: 'https://github.com', label: 'GitHub' }, 67] as const; 68``` 69 70## Styling Rules 71 721. **Use Tailwind utilities only** - No inline styles or CSS modules 732. **Never use margin** - Use `gap` for spacing between children, `padding` for internal spacing 743. **Always include line-height** - Every text element needs leading-* 754. **Scale responsively** - Use breakpoint prefixes: `text-4xl md:text-6xl` 76 77**Good:** 78```typescript 79export const container = 'flex flex-col gap-4 p-6'; 80``` 81 82**Bad:** 83```typescript 84export const container = 'flex flex-col mt-4 mb-8'; // ❌ No margin! 85``` 86 87## Common Patterns 88 89### Base + Variant 90**Card** is the base component. **CardArticle**, **CardRole**, **CardStudy** wrap it with domain-specific logic. 91 92```typescript 93// CardArticle wraps base Card 94import { Card } from '@/components/Card/Card'; 95 96export const CardArticle: React.FC<CardArticleProps> = ({ article }) => ( 97 <a href={article.url}> 98 <Card title={article.title} description={article.subtitle} /> 99 </a> 100); 101``` 102 103### Context-Aware 104**Section** provides theme context. **Button**, **Heading**, etc. read from it. 105 106```typescript 107<Section theme="blue"> 108 <Button /> {/* Automatically styled for blue theme */} 109</Section> 110``` 111 112## Design System 113 114**Colors:** `bones-blue`, `bones-white`, `bones-black`, `bones-yellow` 115**Fonts:** `font-sans` (DM Sans), `font-serif` (DM Serif Display) 116**Themes:** `mono`, `gray`, `yellow`, `blue`, `red`, `purple` 117 118## Quick Start 119 120```bash 121# Create new component 122mkdir src/components/NewComponent 123cd src/components/NewComponent 124 125# Create files 126touch NewComponent.tsx NewComponent.types.ts NewComponent.styles.ts NewComponent.constants.ts 127``` 128 129Look at **Button**, **Card**, or **Navigation** for examples.