Recently Viewed Rail
A horizontally scrolling rail of recently viewed products, with fading edges and snap scrolling.
A horizontally scrolling rail of recently viewed products: the small product cards line up with scroll-snap, both ends fade according to the scroll position, the left and right arrows scroll smoothly, and the cards reveal one at a time as they appear and lift on hover — a good fit as a recall block on a product detail page or at the bottom of the cart.
npx shadcn@latest add https://webberui.com/r/recently-viewed-rail.jsonPlayground
Tune the props live — the code snippet updates as you go, so you can dial in the look you want before copying it.
<RecentlyViewedRail />
Installation
npx shadcn@latest add https://webberui.com/r/recently-viewed-rail.jsonOr, once registries are configured in components.json, install it as @webberui/recently-viewed-rail.
Usage
import { RecentlyViewedRail } from "@/components/ui/recently-viewed-rail";
<RecentlyViewedRail
items={[
{
id: "p1",
name: "Wireless noise-cancelling headphones",
price: "NT$4,990",
hue: 222,
tag: "Electronics",
viewedAt: "5 minutes ago",
},
{ id: "p2", name: "Canvas tote bag", price: "NT$1,280", hue: 36 },
]}
onItemClick={(item) => console.log(item.name)}
/>Props
| Prop | Type | Default | Description |
|---|---|---|---|
items | RecentlyViewedItem[] | — | List of recently viewed products; each has id, name, price, and hue, plus optional tag and viewedAt |
title | string | "Recently viewed" | Section title text |
showArrows | boolean | true | Whether to show the left and right scroll arrows |
cardWidth | number | 168 | Width of a single product card (px) |
onItemClick | (item: RecentlyViewedItem, index: number) => void | — | Callback when a product card is clicked |
className | string | — | Forwarded to the outermost container |
Accessibility
- Product cards are native
<button>s, focusable with Tab, activatable with Enter / Space, and carry a focus-visible ring outline - The left and right arrows have
aria-labels (scroll left / scroll right), and fade out and leave the Tab order when that side can no longer be scrolled - When the user has "reduce motion" enabled at the system level, the reveal stagger and the hover lift animation are disabled and the arrow scrolling jumps instantly instead
- The gradient placeholder product images and the decorative layers are all marked
aria-hidden, while the product name and price are provided as plain text to assistive technology - The section is named with
<section aria-label>, and the product row uses a semantic<ul>/<li>structure
Variant Swatch Picker
A color swatch and size picker with sold-out slashes, a springing selection ring, and low stock hints.
Convenience Store Pickup
Three-step convenience-store pickup picker: chain → city/district → store list with search, hours and a selected-store summary card; brand-neutral, data supplied by props