Page Sections

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.en

New project or installation trouble? Start here →

Playground

Tune the props live — the code snippet updates as you go, so you can dial in the look you want before copying it.

6000
450
Active edited usageDefault props
<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.json

Or, 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

PropTypeDefaultDescription
testimonialsAutoplayQuoteCardItem[]—List of testimonials
eyebrowstring—Small label above the title
titlestring—Section title; also the carousel's accessible name
subtitlestring—Supporting text below the title
autoplaybooleantrueWhether to autoplay; starts paused under reduced motion, but the play button still works
intervalnumber6000Time per entry (ms); falls back to --wb-autoplay-quote-card-interval when omitted
durationnumber450Transition duration (ms); falls back to --wb-autoplay-quote-card-duration when omitted
indexnumber—Controlled current index
defaultIndexnumber0Initial index in uncontrolled mode
onIndexChange(index: number) => void—Called when the index changes
showMediabooleantrueWhether to show the portrait panel on the left (md and up)
classNamestring—Passed through to the root section

AutoplayQuoteCardItem

FieldTypeDefaultDescription
quotestring—Full quote text
namestring—Customer name
rolestring—Job title
companystring—Company name; shown as a text wordmark when companyMark is omitted
ratingnumber—Rating (0–5); shows stars when provided
avatarHuenumber—Hue of the portrait placeholder gradient; derived from the index via the golden angle when omitted
highlightstring—Fragment of the quote to mark with the accent colour (must match exactly)
metric{ value: string; label: string }—Optional result metric and label
photoSrcstring—Portrait photo URL; a gradient + abstract silhouette is shown when omitted
companyMarkReact.ReactNode—Company wordmark (e.g. inline SVG)

How it works

  • Timing variables: --wb-autoplay-quote-card-interval (default 6000ms) and --wb-autoplay-quote-card-duration (default 450ms); the interval / duration props 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 calls play() 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" with aria-roledescription set to carousel and is named by title; the root section uses aria-labelledby to point at the heading
  • Quotes are marked up with figure / blockquote / figcaption; dots are buttons labelled "Testimonial n", the current one carries aria-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-pressed and the label "Pause autoplay"
  • The announcer is aria-live="off" during autoplay so screen readers aren't interrupted every few seconds; it switches to polite on 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