Workshop owners on the invoicing app they run their shop on. It plays by itself and holds while you point at it; pull the strip, use the arrows or click a card to pass the lead.
registry/demos/relay-carousel-demo.tsx
import { RelayCarousel, RelayCarouselItem } from "@/components/ui/relay-carousel";
const makers = [
{
name: "Joaquim Carvalho",
role: "Ceramicist, Barro Studio",
label: "Ceramics · Porto",
quote:
"I used to spend Sunday nights matching invoices to kiln loads. Now an order comes in and the glaze stock counts itself down.",
photo: "1753164725926-dc4de5911e61",
alt: "A bearded potter in a clay-streaked apron raising a tall vase on the wheel",
},
{
name: "Tomasz Wiśniewski",
role: "Owner, Kruszon Bakery",
label: "Bakery · Kraków",
quote:
"Our cafés reorder from a link I sent them once. I know what to bake tomorrow before the ovens have cooled down.",
photo: "1772758632504-361aa9d14a19",
alt: "A baker sliding flatbreads into a brick oven, rounds of dough waiting in front",
},
{
name: "Gareth Lloyd",
role: "Woodcarver, Grain & Gauge",
label: "Woodwork · Leeds",
quote:
"Every commission keeps its timber, hours and deposit on one page. Quoting a carved panel takes ten minutes, not an evening.",
photo: "1783669081274-3db07e6ec196",
alt: "A woodcarver chiseling a relief panel at a cluttered bench under a desk lamp",
},
{
name: "Kenji Arai",
role: "Roaster, Hiraku Coffee",
label: "Coffee · Osaka",
quote:
"Green beans, roast days and wholesale orders finally talk to each other. I buy sacks when the numbers say so, not when I panic.",
photo: "1607681034512-1c9c5fbda608",
alt: "A roaster in ear defenders checking freshly roasted beans under a magnifier lamp",
},
{
name: "Lena Hoffmann",
role: "Florist, Stiel",
label: "Flowers · Leipzig",
quote:
"Wedding season used to live on sticky notes. This year every bouquet had its stems, its order and its invoice before the bride did.",
photo: "1531058240690-006c446962d8",
alt: "A florist at the counter of her flower shop, seen through the plants",
},
{
name: "Idris Hale",
role: "Leatherworker, Hale & Hide",
label: "Leather · Bristol",
quote:
"Custom orders, hides and the balance owed sit on the same screen. I've stopped losing deposits in the gap between them.",
photo: "1534126511673-b6899657816a",
alt: "A craftsman stitching a leather strap on an industrial sewing machine",
},
{
name: "Rafael Moreno",
role: "Mechanic, Cadena Cycles",
label: "Repairs · Valencia",
quote:
"Customers get a message when their bike is ready and pay from the link. My bench stays clear, and so does my inbox.",
photo: "1675798227643-da319f8ee8f7",
alt: "A mechanic's hands tightening the crank on a black bicycle frame",
},
{
name: "Ewan MacLeod",
role: "Printer, Low Tide Press",
label: "Screen print · Edinburgh",
quote:
"A poster run has twelve proofs and three deposits. Field & Fold keeps all of it straight, so I can keep my hands inky.",
photo: "1456456496250-d5e7c0a9b44d",
alt: "A printmaker pulling ink across a silkscreen by the window",
},
];
const photo = (id: string) =>
`https://images.unsplash.com/photo-${id}?auto=format&fit=crop&w=880&h=840&q=80`;
export function RelayCarouselDemo() {
return (
<div className="flex min-h-[var(--demo-height,auto)] w-full flex-col justify-center overflow-hidden rounded-2xl border border-zinc-200 bg-white py-14 text-zinc-950 sm:py-20 dark:border-zinc-800 dark:bg-zinc-950 dark:text-zinc-50">
<RelayCarousel
aria-labelledby="relay-makers-heading"
autoPlay={7000}
heading={
<h2
id="relay-makers-heading"
className="text-[2rem] leading-[1.02] font-semibold tracking-[-0.035em] text-balance @2xl:text-5xl"
>
Small shops,
<br />
<span className="text-zinc-400 dark:text-zinc-500">steady books.</span>
</h2>
}
>
{makers.map((maker) => (
<RelayCarouselItem
key={maker.name}
name={maker.name}
role={maker.role}
label={maker.label}
quote={maker.quote}
image={photo(maker.photo)}
alt={maker.alt}
/>
))}
</RelayCarousel>
</div>
);
}
Live preview, examples and props: https://keyframeui.com/components/relay-carousel#relay-carousel-demo