Product carouselPro
A snapping row of products with receipt style prices, one tab stop and a compare tray.
On this page
ProSix gift picks; tick two or three and compare them from the tray.
Installation
Usage
import { ProductCarousel } from "@/components/ui/chatcn/pro/product-carousel"
<ProductCarousel
title="Gift ideas under $450"
products={results}
onSelect={(p) => openProduct(p.id)}
onCompare={(ids) => openCompare(ids)}
/>Tiles snap one at a time and keep the same height, so prices line up across the row. With onCompare set, each tile gets a Compare toggle on the photo (on hover, always on touch); the first tick raises a tray under the rail with the picked photos stacked, a count against maxCompare and one Compare button that needs two. At the limit the other toggles disable instead of silently replacing a pick. available: false greys a tile and labels it sold out.
Examples
States
ProLoading, a sold out tile with compare full, nothing found and an error.
Props
| Prop | Type | Notes |
|---|---|---|
products | { id, title, merchant?, image?, price, salePrice?, rating?, reviewCount?, delivery?, tag?, available? }[] | The row |
title, description | ReactNode | Heading over the row |
currency, locale | string | Prices format with Intl, tabular figures. Default USD, en-US |
itemWidth | number | Tile width in px. Default 200 |
onSelect | (product) => void | A tile was opened |
compare, defaultCompare, onCompareChange | string[] | Picked ids |
onCompare | (ids) => void | Shows the toggles and the tray |
maxCompare | number | Default 3 |
loading, error, onRetry, empty | States | |
labels | Partial<ProductCarouselLabels> | Every string, for translation |
Keyboard
| Key | Action |
|---|---|
| Tab | Into the row (one stop), then the compare toggle of that tile |
| Left and Right | Move between tiles; the row scrolls to keep focus in view |
| Home and End | First and last tile |
| Space | Toggle compare on the focused toggle |
Accessibility
- The row is a carousel region; each tile is a slide named with its position and title.
- Compare toggles are real checkboxes named with the product.
- The tray count is a polite live region.
Motion
Paging scrolls smoothly, instantly under reduced motion. The tray fades up 4 px in 180 ms. Compare toggles fade in on hover in 150 ms; keyboard focus shows them at once.