Product detailPro
One product in a message: photos, price, stock and delivery, how it fits what was asked, and one Buy button.
On this page
Installation
Usage
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
Props
| Prop | Type | Notes |
|---|---|---|
title, merchant, merchantVerified | string, string, boolean | Identity |
images | { src, alt? }[] | More than one adds a thumbnail strip |
price, salePrice | number | Major units. A lower salePrice shows the saving |
currency, locale | string | Prices format with Intl, tabular figures. Default USD, en-US |
rating, reviewCount | number | Stars out of 5, compact counts from 10,000 |
stock, stockCount | "in-stock" | "low-stock" | "out-of-stock" | "preorder", number | Sold out disables Buy |
delivery, returns, summary | string, string, ReactNode | One 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, href | ReactNode, string | Confirmation line, store link |
loading, error, onRetry, disabled | States | |
labels | Partial<ProductDetailLabels> | Every string, for translation |
Keyboard
| Key | Action |
|---|---|
| Tab | Thumbnails, then Buy and the store link |
| Left and Right | Move between photos in the thumbnail strip |
| Enter or Space | Buy |
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.