Product Card

PreviousNext

A compound component designed for commerce interfaces, featuring multiple layout variants, distinct sizing, and interactive hover states

Twemco Clock

Twemco Clock

Clock

12

Installation

pnpm dlx shadcn@latest add https://deltacomponents.dev/r/product-card.json

Usage

The Product Card uses a compound component pattern to allow maximum flexibility in content composition.

import {
  ProductCard,
  ProductCardContent,
  ProductCardHeader,
  ProductCardImage,
  ProductCardMetric,
  ProductCardSubtitle,
  ProductCardTitle,
} from "@/components/ui/product-card"
 
export default function Example() {
  return (
    <ProductCard className="w-[300px]">
      <ProductCardImage src="/shoe.jpg" alt="Running Shoe" />
      <ProductCardContent>
        <ProductCardHeader>
          <ProductCardTitle>Speed Runner 2</ProductCardTitle>
          <ProductCardSubtitle>Performance Footwear</ProductCardSubtitle>
        </ProductCardHeader>
        <ProductCardMetric>$120</ProductCardMetric>
      </ProductCardContent>
    </ProductCard>
  )
}

Examples

Inner Layout

Use the inner variant to overlay content on top of the image. This is ideal for editorial content or high-impact visuals where space is limited.

Twemco Clock

Twemco Clock

Clock

12

Custom Content

You can overlay badges on the image to indicate status (New, Sale, Sold Out) using the ProductCardBadge component.

Sizing

The component accepts a size prop (sm, default, lg) which automatically scales padding, font-sizes, and badge positioning.

Analogue Pocket

Analogue Pocket

Gaming Console

$219

Grid Layout

Display multiple cards in a responsive grid layout. This example showcases an essay curation using the product card component.

Notes

Creating Images Like Used in Examples

To achieve the clean, product-focused look seen in the demos (especially for the inner variants), you need images with transparent backgrounds.

On macOS:

  1. Right-click your image file in Finder.
  2. Select Quick Actions > Remove Background.
  3. Important: This creates a transparent PNG but preserves the original canvas dimensions. You will likely need to crop the image afterwards to remove excess whitespace so the product fills the card correctly.

Alternatives: If you aren't on macOS, you can use free online tools like Adobe Express or remove.bg to achieve the same result.

Next.js Image Optimization

By default, this component uses a standard HTML <img> tag. As per the Source Code Ownership philosophy, if you are using Next.js, you should modify product-card.tsx to use the next/image component for production.

// In product-card.tsx
import Image from "next/image"
 
// ... inside ProductCardImage
<Image
  src={src}
  alt={alt}
  fill
  className={cn(...)}
/>

Aspect Ratio

The image container enforces a strict aspect-square (1:1) ratio by default. To change this for portrait or landscape cards, override the class on the ProductCardImage sub-component:

<ProductCardImage
  src="..."
  alt="..."
  className="aspect-[3/4]" // Override for portrait mode
/>

API Reference

ProductCard (root)

The root container component.

PropTypeDefaultDescription
variant"default" | "inner""default"Card layout variant - "default" shows content below image, "inner" overlays content on image
size"sm" | "small" | "default" | "lg" | "large""default"Card size affecting padding and text sizes
onCardClick() => void-Callback when the card is clicked
classNamestring-Additional CSS classes

ProductCardImage

Image container with standard img element.

PropTypeDefaultDescription
srcstring-Image source URL (required)
altstring-Image alt text for accessibility (required)
imageClassNamestring-Additional CSS classes for the image element
classNamestring-Additional CSS classes for the container

ProductCardBadge

Interactive badge overlay for the image.

PropTypeDefaultDescription
isActivebooleanfalseWhether the badge is in active/selected state
iconReact.ReactNode-Icon to display before label
onClick(e: React.MouseEvent) => void-Click handler (stops propagation automatically)
classNamestring-Additional CSS classes

ProductCardContent

Container for the card's text content.

PropTypeDefaultDescription
classNamestring-Additional CSS classes

ProductCardHeader

Wrapper for title and subtitle.

PropTypeDefaultDescription
classNamestring-Additional CSS classes

ProductCardTitle

Product title heading.

PropTypeDefaultDescription
classNamestring-Additional CSS classes

ProductCardSubtitle

Product subtitle or category.

PropTypeDefaultDescription
classNamestring-Additional CSS classes

ProductCardMetric

Metric display (price, rating, etc).

PropTypeDefaultDescription
classNamestring-Additional CSS classes