Product Card

Commerce

E-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