This guide explains the structure and usage of React components in the Open Hardware Initiative website.
src/components/
├── ui/ # Reusable UI components (shadcn/ui)
│ ├── button.tsx # Button component
│ ├── card.tsx # Card component
│ ├── dialog.tsx # Modal dialogs
│ └── ... # Other UI primitives
├── HeroSection.tsx # Landing page hero
├── Navbar.tsx # Navigation bar
├── Footer.tsx # Site footer
├── TeamSection.tsx # Team display
├── ProjectCard.tsx # Individual project card
├── EventCard.tsx # Individual event card
└── ... # Other page-specific components
- UI Components (
ui/) - Reusable, generic components (buttons, cards, etc.) - Page Components (
pages/) - Full page layouts - Section Components - Major page sections (hero, team, projects)
- Card Components - Individual item displays (team member, project, event)
- Navbar - Main navigation with mobile menu
- DesktopNavigation - Desktop navigation bar
- MobileNavigation - Mobile hamburger menu
- HeroSection - Landing page hero with call-to-action
- TeamSection - Team member grid display
- ProjectCard - Individual project showcase
- EventCard - Individual event display
- SponsorSection - Sponsor logos and information
- Button - Primary, secondary, and ghost button variants
- Card - Content containers with headers and bodies
- Dialog - Modal popups for forms and confirmations
- Badge - Status indicators and tags
interface ComponentProps {
title: string;
description?: string;
className?: string;
children?: React.ReactNode;
}// Use Tailwind classes for styling
<div className="flex flex-col space-y-4 p-6 bg-white rounded-lg shadow-md">
<h2 className="text-2xl font-bold text-gray-900">{title}</h2>
<p className="text-gray-600">{description}</p>
</div>// Mobile-first responsive classes
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
{/* Content adapts to screen size */}
</div>- Single Responsibility - Each component has one clear purpose
- Reusability - UI components should be generic and reusable
- Props Interface - Always define TypeScript interfaces for props
- Default Props - Provide sensible defaults where appropriate
- Tailwind First - Use Tailwind classes for most styling
- Component Variants - Use class-variance-authority for component variants
- Consistent Spacing - Follow Tailwind spacing scale
- Accessibility - Include proper ARIA labels and semantic HTML
- Memoization - Use React.memo for expensive components
- Lazy Loading - Lazy load components that aren't immediately visible
- Image Optimization - Use proper image formats and sizes
{isOpen && <ApplicationForm />}
{status === 'loading' ? <Spinner /> : <Content />}{teamMembers.map((member) => (
<TeamMemberCard key={member.id} member={member} />
))}const handleClick = (event: React.MouseEvent) => {
event.preventDefault();
// Handle click logic
};// src/components/NewComponent.tsx
import React from 'react';
interface NewComponentProps {
title: string;
// Add other props
}
export const NewComponent: React.FC<NewComponentProps> = ({ title }) => {
return (
<div className="p-4 bg-white rounded-lg">
<h3 className="text-lg font-semibold">{title}</h3>
</div>
);
};// src/components/index.ts
export { NewComponent } from './NewComponent';import { NewComponent } from '@/components/NewComponent';