A product card with image, price, discount badge, wishlist toggle, and add to cart action for shop grids.
The import and the props worth knowing about, in one place.
import { Card4 } from "@/components/beste/component/card4";
// Image and name link to href; heart and CTA stay independently clickable.
<Card4
src="/products/watch.jpg"
name="Atlas Field Watch"
price="$249"
compareAt="$320" // struck-through original price
badge="-22%" // corner badge
rating={4.8}
href="/products/atlas-field-watch"
onAdd={() => console.log("added to cart")}
onWishlist={(on) => console.log("wishlist", on)}
/>
<Card4
src="/products/lamp.jpg"
name="Dune Desk Lamp"
price="$89"
ctaLabel="Buy now"
tone="primary" // CTA: "dark" (default) | "primary"
onAdd={() => console.log("buy now")}
/>Every one of these is in the component already. They are listed because a props table cannot mention a gesture, so nothing else on this page can tell you they exist.
| Hover | The card lifts and the image scales inside its frame; `motion-reduce` turns the movement off. |
|---|
Read from the component's own type, so this cannot drift from what it accepts.
| Prop | Type | Default | Description |
|---|---|---|---|
src* | string | — | Product image URL |
name* | string | — | Product name |
price* | string | — | Current price (e.g. "$249") |
compareAt | string | — | Original price, rendered struck through (e.g. "$320") |
badge | string | — | Corner badge (e.g. "New" or "-22%") |
rating | number | — | Rating value shown next to a star (e.g. 4.8) |
href | string | — | If set, the image and name link to this href |
ctaLabel | string | — | CTA label (defaults to "Add to cart") |
onAdd | React.MouseEventHandler<HTMLButtonElement> | — | CTA click handler |
onWishlist | (wishlisted: boolean) => void | — | Called when the wishlist heart is toggled |
tone | "dark" | "primary" | — | CTA tone |
className | string | — | Additional classes merged onto the root |