頁面區塊 Sections
扇形引言牌組
評價卡像撲克牌一樣扇形展開,hover 時該張抬起、鄰卡讓位,點擊把卡片抽到中央放大閱讀,可依序翻下一張。
把客戶評價做成一手扇形展開的牌。5–7 張直式卡以卡片下方同一個支點依序旋轉,進場時從疊在一起的牌堆以彈簧錯開展開;滑鼠移到或鍵盤聚焦某張,該張抬起、兩側的卡再往外讓位。點一下把它抽到牌組上方中央放大閱讀,其餘卡收攏並淡出;再點一次、按 Esc 或點空白處就放回去,「下一張」按鈕則依序抽出。背景是一組跟著展開角度生成的同心圓弧。抽出索引支援受控/非受控雙模式。
把這個效果裝進你的專案
在專案資料夾執行指令,CLI 會加入原始碼與依賴套件,再依下方使用範例引用元件。
npx webberui@latest add fanned-quote-deckPlayground
即時調整 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 | 型別 | 預設值 | 說明 |
|---|---|---|---|
testimonials | FannedQuoteDeckItem[] | — | 評價資料;建議 5–7 則,牌組才排得開 |
eyebrow | string | "客戶回饋" | 標題上方的小標 |
title | string | "客戶怎麼說" | 區塊標題 |
subtitle | string | "點任一張卡片抽出閱讀,或按「下一張」依序翻看。" | 標題下方的說明文字 |
spread | number | 40 | 扇形總展開角度(deg),平均分配給每張卡 |
showBack | boolean | false | 未抽出的卡片以卡背朝上,抽出時翻面 |
selected | number | null | — | 受控的抽出索引(null 表示沒有抽出);未提供時由元件內部管理 |
defaultSelected | number | null | null | 非受控模式的初始抽出索引 |
onSelectedChange | (index: number | null) => void | — | 抽出索引變動時回呼 |
nextLabel | string | "下一張" | 「下一張」按鈕文字 |
className | string | — | 透傳到最外層 section |
FannedQuoteDeckItem
| 欄位 | 型別 | 預設值 | 說明 |
|---|---|---|---|
quote | string | — | 引言內文(建議 4–5 行內,超過會截斷) |
name | string | — | 客戶姓名 |
role | string | — | 職稱 |
company | string | — | 公司或品牌名稱 |
rating | number | — | 1–5 星評分;未提供則不顯示星等 |
avatarHue | number | — | 頭像與卡背漸層的色相(0–360);未提供時依索引以黃金角度自動分配 |
highlight | string | — | quote 中要以強調色標記的片段(取第一次出現處) |
metric | { value: string; label: string } | — | 卡片底部的成效數字 |
CSS 變數
| 變數 | 預設值 | 說明 |
|---|---|---|
--wb-fanned-quote-deck-stiffness | 340 | 展開、抬起、抽出與翻面的彈簧剛度(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 正反面淡入淡出,內容仍可透過點擊、鍵盤與「下一張」切換