Product Card
CommerceE-commerce product card with image and pricing.
Preview
$
Usage
example.jsx
import { ProductCard } from "@/components/ui/product-card";
export default function Example() {
return <ProductCard />;
}Source Code
Copy this file into components/ui/product-card.jsx in your project.
product-card.jsx
import { forwardRef } from "react";
import { cn } from "@/lib/utils";
const ProductCard = forwardRef(({ className, product = {}, onAddToCart, ...props }, ref) => (
<div ref={ref} className={cn("group w-full max-w-xs overflow-hidden rounded-lg border bg-card shadow-sm transition-shadow hover:shadow-md", className)} {...props}>
<div className="relative aspect-square overflow-hidden bg-muted">
{product.image && <img src={product.image} alt={product.name} className="h-full w-full object-cover transition-transform group-hover:scale-105" />}
{product.badge && <span className="absolute left-2 top-2 rounded-full bg-primary px-2 py-0.5 text-xs font-medium text-primary-foreground">{product.badge}</span>}
</div>
<div className="p-4">
{product.category && <p className="text-xs text-muted-foreground">{product.category}</p>}
<h3 className="mt-1 font-semibold">{product.name}</h3>
<div className="mt-2 flex items-center gap-2">
<span className="text-lg font-bold">${product.price}</span>
{product.originalPrice && <span className="text-sm text-muted-foreground line-through">${product.originalPrice}</span>}
</div>
{onAddToCart && (
<button onClick={() => onAddToCart(product)}
className="mt-3 inline-flex h-9 w-full items-center justify-center rounded-md bg-primary text-sm font-medium text-primary-foreground hover:bg-primary/90"
>Add to Cart</button>
)}
</div>
</div>
));
ProductCard.displayName = "ProductCard";
export { ProductCard };
Quick Install
Make sure you have the cn() utility set up. It requires clsx and tailwind-merge.
npm install clsx tailwind-merge