ProductCard

React SDK guidance for ProductCard.

Exact exports, props, slots, hooks, and runtime behavior belong to SDK package reference. Examples are guidance unless explicitly marked copy-paste-safe.

Review component intent and composition guidance before wiring this component into an app. Then use the live playground to confirm the rendered behavior.

Playground

When to use it

Use ProductCard anywhere shoppers need a fast, repeatable scan of product image, name, and price. It is the default building block for catalog grids, recommendation rails, and search surfaces.

Layout selection

Choose the layout based on scan behavior, not only visual taste:

  • gallery for standard product grids and editorial merch rows
  • horizontal for search, drawers, and tighter list surfaces
  • minimal when image and overlay treatment should dominate the presentation
  • list or stripped when product density matters more than visual drama

Keep product signals stable

Title, price, and merchandising flags should stay in predictable places across layouts. Variation should come from density and image treatment, not from constantly moving key buying signals.

Image behavior

When a gallery card receives multiple images, it can either swipe between them or stay on the first image.

  • imageBehavior="auto" keeps the normal card behavior and also lets parent components influence the image treatment.
  • Inside ProductRecommendations, auto defaults to a single image so the outer rail stays the only carousel in that section.
  • Use imageBehavior="carousel" to force the card-level image swipe back on.
  • Use imageBehavior="single" to always lock the card to its first image.

Data guidance

Treat ProductCard as a display primitive, not as your product model. Normalize product data before it reaches the component so the card can stay focused on presentation. That keeps grid templates simpler and makes it easier to reuse the same card across search, PLP, and recommendation contexts.

If a layout needs more metadata than the core card currently shows, keep the main import and switch to the compound slot surface (ProductCard.Root, ProductCard.ImageArea, ProductCard.Content, and friends) before inventing a parallel product-card abstraction.

Composition and customization

The default prop-based layouts stay the fastest path for standard grids and rails. When the surface needs custom action rows, richer badge placement, or a different wishlist control, keep importing ProductCard from @enadhq/enad-react-sdk/client/storefront and compose the slot parts directly from that same export.

Use ScrollSnapRail when a card or media surface needs custom slide elements but should keep the SDK's scroll-snap rail behavior. It accepts arbitrary children as slides, can be controlled with activeIndex/onIndexChange, supports uncontrolled defaultIndex, exposes stable data-slot overrides, and defaults to containing wheel events so nested rails do not accidentally scroll an outer rail.

import { ScrollSnapRail } from "@enadhq/enad-react-sdk/client/storefront";

<ProductCard.ImageArea className="aspect-[4/5]">
  <ScrollSnapRail activeIndex={activeIndex} onIndexChange={setActiveIndex}>
    {slides.map((slide) => (
      <CustomProductMedia key={slide.id} slide={slide} />
    ))}
  </ScrollSnapRail>
</ProductCard.ImageArea>;

That keeps the API discoverable while still leaving analytics, save-state, custom dots, image warming, and add-to-cart behavior in your own callbacks and slots instead of assuming a built-in provider or product model.

Connected companion

Use ProductCard when the page already owns product data.

If the page wants the SDK to resolve a search-backed product by slug, SKU, or an inline search product record, step up to SearchProductCard from @enadhq/enad-react-sdk/client/search. That connected wrapper keeps ProductCard presentational while mapping Search GraphQL product data into the same card contract.

Review notes

These notes define scoped usage boundaries without claiming exact prop or runtime truth beyond SDK package reference.

ProductCard stays a product-display tile. It can present image, title, price, and merchandising signals, but the caller owns product normalization, destination URLs, analytics, save-state, cart actions, and checkout side effects.

  • Pass already-normalized product data into the card rather than using the card as the product model.
  • Keep card-level actions as callbacks or slots owned by the surrounding PLP, search, recommendation, or merchandising surface.
  • Use connected search wrappers only when the SDK should resolve Search GraphQL product records; otherwise keep ProductCard presentational.

Contract scope

  • Use SDK package reference for exact props, exports, slots, hooks, and runtime behavior.
  • Public import: @enadhq/enad-react-sdk/client/storefront.
  • Playground route: /sandbox?component=ProductCard.
  • Copy/paste scope: guidance-only. Treat examples as guidance until checked against SDK package reference.

Implementation notes

  • ProductCard is a display primitive. Keep PDP media controls, lightbox, and thumbnail behavior in the media components that own them.

ProductCard

# ProductCard > Exact exports, props, slots, hooks, and runtime behavior belong to SDK package reference. Examples are guidance unless explicitly marked copy-paste-safe. Review component intent and composition guidance before wiring this component into an app. Then use the live playground to confirm the rendered behavior. ## Playground - Import path: `@enadhq/enad-react-sdk/client/storefront`. - Live playground: [/components/storefront/product-card](https://sdk.enad.io/components/storefront/product-card). ## When to use it Use `ProductCard` anywhere shoppers need a fast, repeatable scan of product image, name, and price. It is the default building block for catalog grids, recommendation rails, and search surfaces. ## Layout selection Choose the layout based on scan behavior, not only visual taste: - `gallery` for standard product grids and editorial merch rows - `horizontal` for search, drawers, and tighter list surfaces - `minimal` when image and overlay treatment should dominate the presentation - `list` or `stripped` when product density matters more than visual drama > **Keep product signals stable** > > Title, price, and merchandising flags should stay in predictable places across layouts. Variation > should come from density and image treatment, not from constantly moving key buying signals. ## Image behavior When a `gallery` card receives multiple images, it can either swipe between them or stay on the first image. - `imageBehavior="auto"` keeps the normal card behavior and also lets parent components influence the image treatment. - Inside `ProductRecommendations`, `auto` defaults to a single image so the outer rail stays the only carousel in that section. - Use `imageBehavior="carousel"` to force the card-level image swipe back on. - Use `imageBehavior="single"` to always lock the card to its first image. ## Data guidance Treat `ProductCard` as a display primitive, not as your product model. Normalize product data before it reaches the component so the card can stay focused on presentation. That keeps grid templates simpler and makes it easier to reuse the same card across search, PLP, and recommendation contexts. If a layout needs more metadata than the core card currently shows, keep the main import and switch to the compound slot surface (`ProductCard.Root`, `ProductCard.ImageArea`, `ProductCard.Content`, and friends) before inventing a parallel product-card abstraction. ## Composition and customization The default prop-based layouts stay the fastest path for standard grids and rails. When the surface needs custom action rows, richer badge placement, or a different wishlist control, keep importing `ProductCard` from `@enadhq/enad-react-sdk/client/storefront` and compose the slot parts directly from that same export. Use `ScrollSnapRail` when a card or media surface needs custom slide elements but should keep the SDK's scroll-snap rail behavior. It accepts arbitrary children as slides, can be controlled with `activeIndex`/`onIndexChange`, supports uncontrolled `defaultIndex`, exposes stable data-slot overrides, and defaults to containing wheel events so nested rails do not accidentally scroll an outer rail. ```tsx import { ScrollSnapRail } from "@enadhq/enad-react-sdk/client/storefront"; {slides.map((slide) => ( ))} ; ``` That keeps the API discoverable while still leaving analytics, save-state, custom dots, image warming, and add-to-cart behavior in your own callbacks and slots instead of assuming a built-in provider or product model. ## Connected companion Use `ProductCard` when the page already owns product data. If the page wants the SDK to resolve a search-backed product by slug, SKU, or an inline search product record, step up to `SearchProductCard` from `@enadhq/enad-react-sdk/client/search`. That connected wrapper keeps `ProductCard` presentational while mapping Search GraphQL product data into the same card contract. ## Review notes These notes define scoped usage boundaries without claiming exact prop or runtime truth beyond SDK package reference. `ProductCard` stays a product-display tile. It can present image, title, price, and merchandising signals, but the caller owns product normalization, destination URLs, analytics, save-state, cart actions, and checkout side effects. - Pass already-normalized product data into the card rather than using the card as the product model. - Keep card-level actions as callbacks or slots owned by the surrounding PLP, search, recommendation, or merchandising surface. - Use connected search wrappers only when the SDK should resolve Search GraphQL product records; otherwise keep `ProductCard` presentational. ## Contract scope - Use SDK package reference for exact props, exports, slots, hooks, and runtime behavior. - Public import: `@enadhq/enad-react-sdk/client/storefront`. - Playground route: /sandbox?component=ProductCard. - Copy/paste scope: guidance-only. Treat examples as guidance until checked against SDK package reference. ### Implementation notes - `ProductCard` is a display primitive. Keep PDP media controls, lightbox, and thumbnail behavior in the media components that own them.