Autoplay Quote Card
One large centred testimonial card that autoplays, with a bottom progress bar counting down to the next quote; content slides and fades between entries, with pause and manual controls.
A page section that shows one testimonial at a time so readers actually finish it. The centred card has a portrait panel on the left (a gradient + abstract silhouette placeholder, swappable for a real photo via photoSrc) and, on the right, the company wordmark, quote, author and an optional result metric; a 2px accent progress bar along the bottom counts down to the next entry. On change the content slides and fades in the direction of travel, the portrait crossfades, and the card height eases to fit the new quote. Below the card are dot indicators, previous / next buttons and a pause button. Hovering or focusing the card, or switching to another tab, pauses autoplay automatically, and touch devices can swipe left and right.
Bring this into your project
Run this command in your project folder. The CLI adds the source and dependencies; then follow the usage example below.
npx webberui@latest add autoplay-quote-card.enPlayground
Tune the props live — the code snippet updates as you go, so you can dial in the look you want before copying it.
<AutoplayQuoteCard/>
The complete example includes the preview layout and data. Install the component first, then paste this file into your project.
Installation
npx webberui@latest add https://webberui.com/r/autoplay-quote-card.en.jsonOr, once registries are configured in components.json, install it as @webberui/autoplay-quote-card.
Usage
import { AutoplayQuoteCard } from "@/components/ui/autoplay-quote-card";
<AutoplayQuoteCard
eyebrow="客戶怎麼說"
title="一次一則,讀得完整"
testimonials={[
{
quote: "活動頁從兩週縮到兩天上線,行銷自己就能完成。",
name: "林予晴",
role: "品牌經理",
company: "青嶼咖啡",
highlight: "從兩週縮到兩天",
metric: { value: "−86%", label: "上線等待時間" },
},
{
quote: "追蹤畫面好讀之後,客服電話明顯變少。",
name: "陳柏翰",
role: "營運主管",
company: "北辰物流",
rating: 5,
},
]}
interval={6000}
onIndexChange={(i) => console.log(`目前第 ${i + 1} 則`)}
/>The sample strings stay in Chinese to match the Chinese docs: "客戶怎麼說" (What customers say), "一次一則,讀得完整" (One quote at a time, read in full), and 目前第 n 則 (now showing entry n).
Props
| Prop | Type | Default | Description |
|---|---|---|---|
testimonials | AutoplayQuoteCardItem[] | — | List of testimonials |
eyebrow | string | — | Small label above the title |
title | string | — | Section title; also the carousel's accessible name |
subtitle | string | — | Supporting text below the title |
autoplay | boolean | true | Whether to autoplay; starts paused under reduced motion, but the play button still works |
interval | number | 6000 | Time per entry (ms); falls back to --wb-autoplay-quote-card-interval when omitted |
duration | number | 450 | Transition duration (ms); falls back to --wb-autoplay-quote-card-duration when omitted |
index | number | — | Controlled current index |
defaultIndex | number | 0 | Initial index in uncontrolled mode |
onIndexChange | (index: number) => void | — | Called when the index changes |
showMedia | boolean | true | Whether to show the portrait panel on the left (md and up) |
className | string | — | Passed through to the root section |
AutoplayQuoteCardItem
| Field | Type | Default | Description |
|---|---|---|---|
quote | string | — | Full quote text |
name | string | — | Customer name |
role | string | — | Job title |
company | string | — | Company name; shown as a text wordmark when companyMark is omitted |
rating | number | — | Rating (0–5); shows stars when provided |
avatarHue | number | — | Hue of the portrait placeholder gradient; derived from the index via the golden angle when omitted |
highlight | string | — | Fragment of the quote to mark with the accent colour (must match exactly) |
metric | { value: string; label: string } | — | Optional result metric and label |
photoSrc | string | — | Portrait photo URL; a gradient + abstract silhouette is shown when omitted |
companyMark | React.ReactNode | — | Company wordmark (e.g. inline SVG) |
How it works
- Timing variables:
--wb-autoplay-quote-card-interval(default6000ms) and--wb-autoplay-quote-card-duration(default450ms); theinterval/durationprops win when provided. The accent colour comes from--wb-autoplay-quote-card-accent(light default#0d9488, dark#2dd4bf). - The progress bar is driven by motion animation controls: pausing calls
pause()and holds it in place, resuming callsplay()for only the remaining time rather than restarting the countdown. - There are four pause sources: the pause button, mouse hover, focus inside the card, and a hidden tab (
document.hidden); any one of them pauses autoplay. - Card height is tweened with motion from the measured content, so quotes of different lengths don't make the layout below jump.
- Avatars need no photo: on narrow screens or with
showMedia={false}, initials (last two characters for CJK names, first letters for Latin names) sit on a deterministic hue gradient.
Accessibility
- The carousel container is
role="region"witharia-roledescriptionset to carousel and is named bytitle; the rootsectionusesaria-labelledbyto point at the heading - Quotes are marked up with
figure/blockquote/figcaption; dots are buttons labelled "Testimonial n", the current one carriesaria-current, and the arrow keys move between entries inside the dot group - With autoplay on by default there is always a visible pause button (WCAG 2.2.2), with
aria-pressedand the label "Pause autoplay" - The announcer is
aria-live="off"during autoplay so screen readers aren't interrupted every few seconds; it switches topoliteon manual navigation or when paused - When the user's system has reduce motion enabled, autoplay starts off and slides and scaling become a 150ms fade; entries can still be changed with the buttons
Star-Rated Reviews
A row of rated testimonials. The overall score counts up at the top while each card's stars fill one by one with fractional ratings, alongside a product thumbnail and a verified-purchase badge.
3D Tilt Review Card
A slightly askew testimonial card that tilts in 3D perspective with a moving sheen as the pointer moves, the quote floating above the surface, flipping over to switch entries.