# Product Card

- Page: <https://kznlabs.github.io/labsUI/components/product-card>

## Product Card (`product-card`, block)

Shop tile: photos in an AspectRatio (a swipeable Carousel with dots when there are several), sale price, Badge and add-to-cart Button.

- Install: `npx @kznlabs/labsui add product-card`
- Docs: <https://kznlabs.github.io/labsUI/components/product-card>
- Brings: aspect-ratio, badge, button, button-variants, carousel, utils
- npm: clsx@^2.1.1, lucide-react@1.63.0, motion@14.7.1, tailwind-merge@^3.7.0

### API

- `<ProductCard>`: Shop tile: photos in an AspectRatio (a Carousel when there are several), name, price, badge, add button.
  - `media: ReactNode[]`: Photos (`<img>`), one per slide. Several become a swipeable carousel with dots.
  - `name: string`: Product name, the card's heading.
  - `price: number`: Current price in major units, e.g. 49.99.
  - `addLabel?: ReactNode` = `"Add to cart"`: Add button text.
  - `badge?: string`: Small label over the media, e.g. "New".
  - `compareAt?: number`: Struck-through original price for a sale.
  - `currency?: string` = `"USD"`: ISO 4217 code for the price.
  - `href?: string`: Product page link for the name.
  - `locale?: string` = `"en-US"`: BCP 47 locale for number formatting.
  - `onAddToCart?: () => void`: Shows the add button; called when it is pressed.
  - `ratio?: number` = `4 / 3`: Media width/height, e.g. 1 for square.

### Usage

```tsx
<ProductCard name="Clip camera" price={279} compareAt={349} badge="−20%" media={[<img … />, <img … />]} onAddToCart={add} />
```

### Example: product-grid.tsx

```tsx
import { ProductCard } from "@/components/blocks/product-card";

type Product = {
  id: string;
  name: string;
  price: number;
  compareAt?: number;
  images: string[];
};

export function ProductGrid({
  products,
  onAdd,
}: {
  products: Product[];
  onAdd: (id: string) => void;
}) {
  return (
    <div className="grid gap-4 sm:grid-cols-2 lg:grid-cols-3">
      {products.map((p) => (
        <ProductCard
          key={p.id}
          name={p.name}
          price={p.price}
          compareAt={p.compareAt}
          badge={p.compareAt ? "Sale" : undefined}
          href={`/products/${p.id}`}
          media={p.images.map((src) => <img key={src} src={src} alt="" />)}
          onAddToCart={() => onAdd(p.id)}
        />
      ))}
    </div>
  );
}
```
