頁面區塊 Sections

扇形引言牌組

評價卡像撲克牌一樣扇形展開,hover 時該張抬起、鄰卡讓位,點擊把卡片抽到中央放大閱讀,可依序翻下一張。

把客戶評價做成一手扇形展開的牌。5–7 張直式卡以卡片下方同一個支點依序旋轉,進場時從疊在一起的牌堆以彈簧錯開展開;滑鼠移到或鍵盤聚焦某張,該張抬起、兩側的卡再往外讓位。點一下把它抽到牌組上方中央放大閱讀,其餘卡收攏並淡出;再點一次、按 Esc 或點空白處就放回去,「下一張」按鈕則依序抽出。背景是一組跟著展開角度生成的同心圓弧。抽出索引支援受控/非受控雙模式。

把這個效果裝進你的專案

在專案資料夾執行指令,CLI 會加入原始碼與依賴套件,再依下方使用範例引用元件。

npx webberui@latest add fanned-quote-deck

還沒有專案,或安裝遇到問題?看快速開始 →

Playground

即時調整 props、程式碼片段同步更新——直接試出你要的樣子再複製。

40
340
編輯中的呼叫預設屬性
<FannedQuoteDeck/>

完整範例包含預覽的排版與資料。先安裝元件,再把範例檔貼入你的專案。

安裝

npx webberui@latest add https://webberui.com/r/fanned-quote-deck.json

或在 components.json 設定 registries 後,改用 @webberui/fanned-quote-deck 安裝。

使用

import { FannedQuoteDeck } from "@/components/ui/fanned-quote-deck";

<FannedQuoteDeck
  title="客戶怎麼說"
  spread={40}
  testimonials={[
    {
      quote: "以前每週要花半天對帳,現在十分鐘就看完。",
      name: "林雅婷",
      role: "營運經理",
      company: "青嶼咖啡",
      rating: 5,
      highlight: "十分鐘就看完",
    },
    { quote: "司機端的介面簡單到不用教。", name: "陳柏宇", company: "北辰物流" },
    // …建議 5–7 則
  ]}
  onSelectedChange={(index) => console.log(index)}
/>

Props

Prop型別預設值說明
testimonialsFannedQuoteDeckItem[]—評價資料;建議 5–7 則,牌組才排得開
eyebrowstring"客戶回饋"標題上方的小標
titlestring"客戶怎麼說"區塊標題
subtitlestring"點任一張卡片抽出閱讀,或按「下一張」依序翻看。"標題下方的說明文字
spreadnumber40扇形總展開角度(deg),平均分配給每張卡
showBackbooleanfalse未抽出的卡片以卡背朝上,抽出時翻面
selectednumber | null—受控的抽出索引(null 表示沒有抽出);未提供時由元件內部管理
defaultSelectednumber | nullnull非受控模式的初始抽出索引
onSelectedChange(index: number | null) => void—抽出索引變動時回呼
nextLabelstring"下一張"「下一張」按鈕文字
classNamestring—透傳到最外層 section

FannedQuoteDeckItem

欄位型別預設值說明
quotestring—引言內文(建議 4–5 行內,超過會截斷)
namestring—客戶姓名
rolestring—職稱
companystring—公司或品牌名稱
ratingnumber—1–5 星評分;未提供則不顯示星等
avatarHuenumber—頭像與卡背漸層的色相(0–360);未提供時依索引以黃金角度自動分配
highlightstring—quote 中要以強調色標記的片段(取第一次出現處)
metric{ value: string; label: string }—卡片底部的成效數字

CSS 變數

變數預設值說明
--wb-fanned-quote-deck-stiffness340展開、抬起、抽出與翻面的彈簧剛度(damping 固定 30);掛載時讀取一次
--wb-fanned-quote-deck-accent#0d9488(深色 #2dd4bf)小標、引號、標記片段、成效數字與焦點框的強調色

細節

  • 扇形做法:每張卡的 transform-origin 設在 50% 140%(卡片底部下方),只轉角度不平移,整副牌就以同一個支點展開;角度為 -spread/2 到 spread/2 平均分配。
  • Hover 或聚焦時該張上移 24px、角度減半,左右兩側的卡再各外推 4°;抽出時該卡轉正、上移並放大 1.15 倍,其餘卡收攏到 spread × 0.6 並降到 60% 不透明度。
  • 進場展開只在第一次以 50ms 錯開;之後的 hover 與抽出都立即反應,不再帶延遲。
  • 頭像不用照片:中文姓名取末兩字、拉丁姓名取首尾字母,搭配依黃金角度(137.508°)分配的雙色漸層,結果是確定性的,SSR 與客戶端一致。
  • 背景同心圓弧的圓心就是扇形支點,弧長與輻射線跟著 spread 與張數計算;座標固定到小數兩位,避免不同瀏覽器的三角函數末位差異造成水合不一致。
  • 觸控裝置不觸發 hover 抬起(只認滑鼠的 pointer 事件),避免點完後卡片一直停在抬起狀態。

可及性

  • 根元素為 <section aria-labelledby>,指向區塊標題;每則評價以 figure/blockquote/figcaption 呈現
  • 每張卡是 role="button",以 aria-pressed 表示是否抽出,aria-label 含姓名、公司與「第幾張,共幾張」,aria-describedby 指向引言內文
  • 牌組採 roving tabindex:Tab 只會停在一張卡上,←/→(或 ↑/↓)在卡片間移動焦點並抬起該張,Home/End 跳到首尾;Enter 或空白鍵抽出/放回,Esc 放回
  • 抽出後,卡片內容寫進 aria-live="polite" 區域由螢幕閱讀器朗讀
  • 「下一張」是原生 button,旁邊顯示目前序號;所有可互動元素都有 focus-visible 焦點框
  • 使用者系統開啟「減少動態效果」時,展開、抬起與抽出的位移與旋轉直接到位,3D 翻面改為 150ms 正反面淡入淡出,內容仍可透過點擊、鍵盤與「下一張」切換