# Component Dependency Map This document visualizes how components are composed in the atomic structure. ## App Header Composition ``` AppHeader (organism) ├── NavigationMenu (organism) │ ├── Sheet (shadcn) │ ├── NavigationGroupHeader (molecule) │ │ └── CaretDown icon │ └── NavigationItem (molecule) │ ├── Icon │ ├── Label │ └── Badge (shadcn) ├── AppBranding (molecule) │ ├── AppLogo (atom) │ │ └── Code icon │ └── Title + Subtitle text ├── SaveIndicator (molecule) │ ├── StatusIcon (atom) │ │ ├── CheckCircle icon (saved) │ │ └── CloudCheck icon (synced) │ └── Time text ├── ProjectManager (feature) └── ToolbarActions (organism) └── ToolbarButton (molecule) × 5 ├── Button (shadcn) └── Tooltip (shadcn) ``` ## Page Header Composition ``` PageHeader (organism) └── PageHeaderContent (molecule) ├── TabIcon (atom) │ └── Icon with gradient wrapper ├── Title text └── Description text ``` ## Navigation Menu Composition ``` NavigationMenu (organism) ├── Sheet (shadcn) │ ├── SheetTrigger │ │ └── Button with List icon │ └── SheetContent │ ├── SheetHeader with title │ ├── Expand/Collapse buttons │ └── ScrollArea (shadcn) │ └── Collapsible (shadcn) × N groups │ ├── NavigationGroupHeader (molecule) │ │ ├── CaretDown icon │ │ ├── Group label │ │ └── Item count │ └── CollapsibleContent │ └── NavigationItem (molecule) × N │ ├── Icon │ ├── Label │ └── Badge (optional) ``` ## Feature Component Examples ### Dashboard Stats Grid ``` ProjectDashboard (feature) └── Grid of StatCard (molecule) × N ├── IconWrapper (atom) │ └── Feature icon ├── Label text └── Value text ``` ### Empty States ``` EmptyState (molecule) ├── EmptyStateIcon (atom) │ └── Icon with gradient background ├── Title text ├── Description text └── Action button (optional) ``` ### Loading States ``` LoadingState (molecule) ├── LoadingSpinner (atom) │ └── Animated spinner └── Message text ``` ## Component Import Graph ``` App.tsx ├── imports organisms │ ├── AppHeader │ │ ├── imports molecules │ │ │ ├── AppBranding │ │ │ ├── SaveIndicator │ │ │ └── ToolbarButton │ │ └── imports atoms │ │ ├── AppLogo │ │ ├── StatusIcon │ │ └── ErrorBadge │ ├── PageHeader │ │ └── imports molecules │ │ └── PageHeaderContent │ │ └── imports atoms │ │ └── TabIcon │ └── NavigationMenu │ ├── imports molecules │ │ ├── NavigationGroupHeader │ │ └── NavigationItem │ └── imports config │ └── navigation-config.tsx └── imports features ├── CodeEditor ├── ModelDesigner ├── ProjectDashboard └── ... (more features) ``` ## Atomic Levels Quick Reference ### Level 1: Atoms (7 components) - `AppLogo` - Application logo icon - `TabIcon` - Icon with styling variants - `StatusIcon` - Status indicator (saved/synced) - `ErrorBadge` - Badge showing error count - `IconWrapper` - Styled icon wrapper - `LoadingSpinner` - Animated loading spinner - `EmptyStateIcon` - Large icon for empty states ### Level 2: Molecules (10 components) - `SaveIndicator` - Shows save status with time - `AppBranding` - Logo + app name + tagline - `PageHeaderContent` - Page title with icon and description - `ToolbarButton` - Button with tooltip - `NavigationItem` - Navigation link with badge - `NavigationGroupHeader` - Collapsible group header - `EmptyState` - Empty state with icon, title, description - `LoadingState` - Loading indicator with message - `StatCard` - Statistic card with icon and value - `LabelWithBadge` - Label with optional badge ### Level 3: Organisms (4 components) - `NavigationMenu` - Complete navigation sidebar - `PageHeader` - Page header with context - `ToolbarActions` - Toolbar with multiple buttons - `AppHeader` - Complete application header ### Level 4: Features (20+ components) See `/components` directory for full list of feature components. ## Data Flow Example: Save Indicator ``` User makes change ↓ App.tsx updates KV store ↓ setLastSaved(Date.now()) ↓ AppHeader receives lastSaved prop ↓ SaveIndicator (molecule) receives lastSaved ↓ Calculates isRecent = (now - lastSaved < 3s) ↓ Renders StatusIcon (atom) with type based on isRecent ↓ StatusIcon renders CheckCircle (recent) or CloudCheck (older) ``` ## Styling Patterns ### Gradients ```css /* Used in: AppLogo, TabIcon, EmptyStateIcon */ .gradient { @apply bg-gradient-to-br from-primary to-accent; } .gradient-muted { @apply bg-gradient-to-br from-muted to-muted/50; } .gradient-subtle { @apply bg-gradient-to-br from-primary/20 to-accent/20; } ``` ### Responsive Sizing ```css /* Mobile-first approach used throughout */ .text-base sm:text-xl /* Headings scale up on larger screens */ .w-8 sm:w-10 /* Icons grow on larger screens */ .gap-2 sm:gap-3 /* Spacing increases on larger screens */ .hidden sm:block /* Show on larger screens only */ .hidden sm:flex /* Show as flex on larger screens */ ``` ### Icon Sizes ```tsx // Consistent icon sizing across components // Badges, small UI elements // Toolbar buttons, navigation items // Standard buttons // Logo, prominent buttons // Page headers ``` ## Testing Strategy ### Unit Tests (Atoms) Test individual atoms in isolation: ```typescript describe('StatusIcon', () => { it('renders CheckCircle when type is saved', () => { render() expect(screen.getByTestId('check-circle')).toBeInTheDocument() }) }) ``` ### Integration Tests (Molecules) Test molecule composition: ```typescript describe('SaveIndicator', () => { it('shows "Saved" text when recently saved', () => { const lastSaved = Date.now() - 1000 render() expect(screen.getByText('Saved')).toBeInTheDocument() }) }) ``` ### E2E Tests (Organisms) Test complete user flows: ```typescript describe('NavigationMenu', () => { it('navigates to code editor when item clicked', () => { render() userEvent.click(screen.getByText('Code Editor')) expect(onTabChange).toHaveBeenCalledWith('code') }) }) ``` ## Performance Considerations ### Memoization Strategy ```typescript // Atoms: Usually pure, no memo needed export function AppLogo() { ... } // Molecules: Memo when props are complex export const SaveIndicator = memo(({ lastSaved }) => { ... }) // Organisms: Always memo to prevent re-renders export const NavigationMenu = memo(({ activeTab, ... }) => { ... }) ``` ### Code Splitting ```typescript // Feature components are lazy-loaded const CodeEditor = lazy(() => import('@/components/CodeEditor')) const ModelDesigner = lazy(() => import('@/components/ModelDesigner')) // Atoms and molecules are NOT lazy-loaded (too small, used everywhere) ``` ## Accessibility Patterns ### Keyboard Navigation ```tsx // All interactive elements support keyboard