import { ReactNode } from 'react'
interface CardProps {
children: ReactNode
className?: string
}
export function Card({ children, className = '' }: CardProps) {
return (
<div className={`bg-white rounded-lg shadow ${className}`}>
{children}
</div>
)
}
interface CardHeaderProps {
children: ReactNode
actions?: ReactNode
}
export function CardHeader({ children, actions }: CardHeaderProps) {
return (
<div className="flex items-center justify-between px-6 py-4 border-b">
<div>{children}</div>
{actions && <div className="flex gap-2">{actions}</div>}
</div>
)
}
export function CardBody({ children }: { children: ReactNode }) {
return <div className="px-6 py-4">{children}</div>
}
export function CardFooter({ children }: { children: ReactNode }) {
return <div className="px-6 py-4 border-t bg-gray-50">{children}</div>
}
Card.Header = CardHeader
Card.Body = CardBody
Card.Footer = CardFooter
function PostCard({ post }: { post: Post }) {
return (
<Card>
<Card.Header
actions={
<>
<button>Edit</button>
<button>Delete</button>
</>
}
>
<h2>{post.title}</h2>
</Card.Header>
<Card.Body>
<p>{post.excerpt}</p>
</Card.Body>
<Card.Footer>
<div className="flex gap-4">
<span>{post.likes_count} likes</span>
<span>{post.comments_count} comments</span>
</div>
</Card.Footer>
</Card>
)
}
React favors composition over inheritance for code reuse. Instead of extending component classes, I compose smaller components into larger ones. Higher-order components (HOCs) wrap components to add behavior, while render props pass rendering logic as functions. The children prop enables slot-based composition where parent components control layout but children provide content. Custom hooks extract stateful logic without component wrappers. I use compound components for flexible APIs that share state via context. This compositional approach creates more flexible, testable code than inheritance hierarchies. It's the React way of achieving polymorphism and code reuse.