Card carousel
Horizontal results such as places, products or events. Cards snap one by one, arrows page the rail and disable at either end, and images hold their frame while they load.
On this page
Places that snap card by card, with arrows that disable at either end.
Installation
Usage
import { CardCarousel } from "@/components/ui/chatcn/card-carousel"
<CardCarousel
title="Places to work from this afternoon"
items={places}
onSelect={(item) => send(`Tell me more about ${item.title}`)}
/>Examples
Loading and empty
Reserved cards while results load, and a search with no results.
Props
| Prop | Type | Notes |
|---|---|---|
items | CarouselItem[] | id, title, subtitle?, image?, price?, rating?, reviews?, meta?, badge?, href? |
itemWidth | number | Default 224 |
aspect | number | Image ratio. Default 4 / 3 |
onSelect | (item, index) => void | Cards become buttons; with href they are links |
renderItem | (item, index) => ReactNode | Your own card |
expectedCount, loading, streaming, empty |
Keyboard
| Key | Action |
|---|---|
Tab | Move through cards; the rail scrolls the focused card into view |
Enter | Open or select the focused card |
Accessibility
- A labelled carousel region; each card is a slide named with its position and title.
- Arrow buttons have labels and disable at the ends. Ratings carry a hidden word, not just a star.
Motion
- Paging scrolls smoothly, instantly under reduced motion. Images fade in over 200 ms. Cards that stream in rise 4 px once; a finished list appears at once.