Skip to content
Sign in
CommerceProduct detailMenu

Product detailPro

One product in a message: photos, price, stock and delivery, how it fits what was asked, and one Buy button.

ProThe agent's pick checked against what was asked, bought from the card.

Installation

$ pnpm dlx shadcn@latest add @chatcn-pro/product-detail

Usage

tsx
import { ProductDetail } from "@/components/ui/chatcn/pro/product-detail"

<ProductDetail
  title="Tarn 22 L daypack"
  merchant="Northfold Supply"
  images={[{ src: "/daypack.webp" }]}
  price={138}
  stock="in-stock"
  delivery="Arrives Sat 8 Nov"
  matches={[{ label: "Under $150", met: true }, { label: "Before Friday", met: false }]}
  onBuy={() => store.buy("tarn")}
/>

The fit checklist is the part a store page cannot show: each thing the person asked for, ticked when it is met and marked with a dash when it is not, so the agent's pick is honest about its gaps. Prices set the major units in full ink and step the currency sign and cents back a shade, the way a receipt reads. The Buy button names the price, keeps its footprint while the order goes through and becomes the confirmation; a rejected onBuy shows its message under the button. wide puts the gallery beside the details once the card is wider than 32 rem; compact stacks.

Examples

States

ProCompact and on sale, sold out with a long title, a failed order, loading, error and a pre-order.

Props

PropTypeNotes
title, merchant, merchantVerifiedstring, string, booleanIdentity
images{ src, alt? }[]More than one adds a thumbnail strip
price, salePricenumberMajor units. A lower salePrice shows the saving
currency, localestringPrices format with Intl, tabular figures. Default USD, en-US
rating, reviewCountnumberStars out of 5, compact counts from 10,000
stock, stockCount"in-stock" | "low-stock" | "out-of-stock" | "preorder", numberSold out disables Buy
delivery, returns, summarystring, string, ReactNodeOne line each
matches{ label, met }[]What the person asked for
layout"wide" | "compact"Default wide
onBuy() => unknown | Promise<unknown>Reject with an Error to show its message
boughtNote, hrefReactNode, stringConfirmation line, store link
loading, error, onRetry, disabledStates
labelsPartial<ProductDetailLabels>Every string, for translation

Keyboard

KeyAction
TabThumbnails, then Buy and the store link
Left and RightMove between photos in the thumbnail strip
Enter or SpaceBuy

Accessibility

  • The card is an article named by the product title.
  • Thumbnails are a radio group with one tab stop; each names its position.
  • Fit items carry hidden Meets or Does not meet text; the dash and tick are never the only signal.
  • The prices read as one amount each, with the struck price introduced as Was.

Motion

Photos crossfade in 200 ms. The Buy button swaps its label in place with a 180 ms blur fade; the confirmation line fades up 4 px. Reduced motion keeps the fades only.