# Atomic Component Usage Examples This document provides practical examples of using the atomic component library. ## Example 1: Creating a New Feature Header ```tsx import { PageHeaderContent } from '@/components/molecules' import { Code } from '@phosphor-icons/react' export function MyFeatureHeader() { return (
} description="Feature description here" />
) } ``` ## Example 2: Creating a Toolbar with Actions ```tsx import { ToolbarButton } from '@/components/molecules' import { Plus, Download, Sparkle } from '@phosphor-icons/react' export function MyToolbar() { return (
} label="Add Item" onClick={() => console.log('Add')} /> } label="Export" onClick={() => console.log('Export')} variant="default" /> } label="AI Generate" onClick={() => console.log('AI')} />
) } ``` ## Example 3: Empty State with Action ```tsx import { EmptyState } from '@/components/molecules' import { Button } from '@/components/ui/button' import { FileCode } from '@phosphor-icons/react' export function NoFilesView() { return ( } title="No files yet" description="Create your first file to get started with your project" action={ } /> ) } ``` ## Example 4: Loading State ```tsx import { LoadingState } from '@/components/molecules' export function LoadingFiles() { return } ``` ## Example 5: Statistics Dashboard ```tsx import { StatCard } from '@/components/molecules' import { Code, Database, Tree } from '@phosphor-icons/react' export function ProjectStats({ fileCount, modelCount, componentCount }) { return (
} label="Files" value={fileCount} /> } label="Models" value={modelCount} variant="primary" /> } label="Components" value={componentCount} />
) } ``` ## Example 6: Custom Navigation Group ```tsx import { NavigationItem } from '@/components/molecules' import { Code, Database, Tree } from '@phosphor-icons/react' export function MyNavigationSection({ activeTab, onNavigate }) { const items = [ { id: 'code', label: 'Code', icon: , value: 'code' }, { id: 'models', label: 'Models', icon: , value: 'models', badge: 5 }, { id: 'components', label: 'Components', icon: , value: 'components' }, ] return (
{items.map((item) => ( onNavigate(item.value)} /> ))}
) } ``` ## Example 7: Using Atoms Directly ```tsx import { StatusIcon, ErrorBadge, LoadingSpinner } from '@/components/atoms' export function StatusIndicators({ isSaved, errorCount, isLoading }) { return (
{isLoading && } {isSaved && } {errorCount > 0 && (
Errors
)}
) } ``` ## Example 8: Building a Custom Molecule ```tsx // Create: src/components/molecules/FeatureCard.tsx import { Card } from '@/components/ui/card' import { IconWrapper } from '@/components/atoms' import { Button } from '@/components/ui/button' interface FeatureCardProps { icon: React.ReactNode title: string description: string enabled: boolean onToggle: () => void } export function FeatureCard({ icon, title, description, enabled, onToggle, }: FeatureCardProps) { return (

{title}

{description}

) } ``` ## Example 9: Building a Custom Organism ```tsx // Create: src/components/organisms/FeatureGrid.tsx import { FeatureCard } from '@/components/molecules/FeatureCard' import { ScrollArea } from '@/components/ui/scroll-area' interface Feature { id: string icon: React.ReactNode title: string description: string enabled: boolean } interface FeatureGridProps { features: Feature[] onToggle: (featureId: string) => void } export function FeatureGrid({ features, onToggle }: FeatureGridProps) { return (
{features.map((feature) => ( onToggle(feature.id)} /> ))}
) } ``` ## Example 10: Responsive Component Pattern ```tsx import { AppBranding, SaveIndicator } from '@/components/molecules' import { ToolbarButton } from '@/components/molecules' import { useIsMobile } from '@/hooks/use-mobile' import { Menu, Search } from '@phosphor-icons/react' export function ResponsiveHeader({ lastSaved, onSearch, onMenu }) { const isMobile = useIsMobile() return (
{isMobile ? ( <> } label="Menu" onClick={onMenu} /> } label="Search" onClick={onSearch} /> ) : ( <> } label="Search (Ctrl+K)" onClick={onSearch} /> )}
) } ``` ## Best Practices Summary ### ✅ DO: - Use atoms for single-purpose UI elements - Compose molecules from atoms - Build organisms from molecules and atoms - Keep feature components for complex, domain-specific logic - Export all components from index files - Use TypeScript interfaces for all props - Add descriptive comments to complex compositions ### ❌ DON'T: - Import organisms in atoms - Import molecules in atoms - Duplicate atom functionality - Mix business logic into atoms or molecules - Skip TypeScript types - Create "god components" that do everything ## Migration Checklist When refactoring an existing component: 1. ☐ Identify reusable parts 2. ☐ Extract atoms (icons, badges, wrappers) 3. ☐ Create molecules (combinations of atoms) 4. ☐ Build organisms (complex compositions) 5. ☐ Update imports in parent components 6. ☐ Add to appropriate index.ts file 7. ☐ Update documentation 8. ☐ Test thoroughly ## Quick Start Template ```tsx // 1. Create your atom // src/components/atoms/MyAtom.tsx export function MyAtom({ value }: { value: string }) { return {value} } // 2. Update atoms/index.ts export { MyAtom } from './MyAtom' // 3. Create your molecule // src/components/molecules/MyMolecule.tsx import { MyAtom } from '@/components/atoms' export function MyMolecule({ label, value }) { return (
) } // 4. Update molecules/index.ts export { MyMolecule } from './MyMolecule' // 5. Use in your feature import { MyMolecule } from '@/components/molecules' export function MyFeature() { return } ``` ## Component Storybook Template ```tsx // Create: src/components/atoms/MyAtom.stories.tsx import type { Meta, StoryObj } from '@storybook/react' import { MyAtom } from './MyAtom' const meta: Meta = { title: 'Atoms/MyAtom', component: MyAtom, tags: ['autodocs'], } export default meta type Story = StoryObj export const Default: Story = { args: { value: 'Hello World', }, } export const LongText: Story = { args: { value: 'This is a much longer piece of text to test wrapping', }, } ``` ## Testing Template ```tsx // Create: src/components/atoms/__tests__/MyAtom.test.tsx import { render, screen } from '@testing-library/react' import { MyAtom } from '../MyAtom' describe('MyAtom', () => { it('renders the value', () => { render() expect(screen.getByText('test')).toBeInTheDocument() }) it('handles empty value', () => { render() expect(screen.queryByText(/./)).not.toBeInTheDocument() }) }) ``` ## TypeScript Patterns ```tsx // Atom props - simple and focused interface AtomProps { value: string variant?: 'default' | 'primary' size?: 'sm' | 'md' | 'lg' } // Molecule props - combination of atoms interface MoleculeProps { icon: React.ReactNode label: string value: string | number onClick?: () => void } // Organism props - complex with callbacks interface OrganismProps { items: Item[] activeId: string | null onItemSelect: (id: string) => void onItemDelete: (id: string) => void onItemCreate: () => void } ``` ## Performance Tips ```tsx // Memoize expensive computations in molecules/organisms const sortedItems = useMemo( () => items.sort((a, b) => a.name.localeCompare(b.name)), [items] ) // Memoize callback functions const handleClick = useCallback(() => { onItemSelect(item.id) }, [item.id, onItemSelect]) // Use React.memo for expensive renders export const ExpensiveMolecule = memo(function ExpensiveMolecule(props) { // Complex rendering logic }) ```