互動編排
字卡組
背單字式的 React 字卡組元件:點擊或空白鍵 3D 翻面、左右拖曳或方向鍵分成「會/不會」,底部進度條與計數,結束顯示正確率圓環並可重來或只複習不會的。
背單字、記術語用的字卡組。點卡片或按空白鍵以 spring 3D 翻面;往右拖或按 → 標記「會」、往左拖或按 ← 標記「不會」,拖過門檻或甩得夠快,卡片就會旋轉甩出畫面,下一張從預覽位浮上來。底部有進度條與「會/不會」小統計,可用 Backspace 撤回上一張;一輪結束後換成統計卡,顯示正確率圓環,可以「重來全部」或「只複習不會的」。
把這個效果裝進你的專案
在專案資料夾執行指令,CLI 會加入原始碼與依賴套件,再依下方使用範例引用元件。
npx webberui@latest add flashcard-deckPlayground
即時調整 props、程式碼片段同步更新——直接試出你要的樣子再複製。
260
編輯中的呼叫預設屬性
<FlashcardDeck/>
完整範例包含預覽的排版與資料。先安裝元件,再把範例檔貼入你的專案。
安裝
npx webberui@latest add https://webberui.com/r/flashcard-deck.json或在 components.json 設定 registries 後,改用 @webberui/flashcard-deck 安裝。
使用
import { FlashcardDeck } from "@/components/ui/flashcard-deck";
const cards = [
{ id: "persist", front: "堅持", back: "persist(v.)", hint: "不放棄" },
{ id: "curious", front: "好奇", back: "curious(adj.)" },
{ id: "hesitate", front: "猶豫", back: "hesitate(v.)" },
];
<FlashcardDeck
cards={cards}
onResult={(id, known) => console.log(id, known ? "會" : "不會")}
onComplete={(results) => console.log("本輪結果", results)}
/>Props
| Prop | 型別 | 預設值 | 說明 |
|---|---|---|---|
cards | FlashcardItem[] | — | 字卡陣列 |
onResult | (id: string, known: boolean) => void | — | 每分類一張卡時觸發 |
onComplete | (results: FlashcardResult[]) => void | — | 一輪全部分類完時觸發,結果依作答順序排列 |
stiffness | number | 260 | 翻面 spring 的 stiffness(damping 固定 24) |
showProgress | boolean | true | 顯示底部進度條、計數與「會/不會」小統計 |
allowUndo | boolean | true | 允許以 Backspace/U 或撤回按鈕退回上一張 |
shuffle | boolean | false | 以 seed 確定性洗牌 |
seed | number | 1 | 洗牌種子;同一個 seed 永遠得到同一個順序 |
labels | Partial<FlashcardDeckLabels> | — | 介面文字覆寫(按鈕、宣告、位置描述等) |
className | string | — | 透傳到最外層容器 |
FlashcardItem
| 欄位 | 型別 | 預設值 | 說明 |
|---|---|---|---|
id | string | — | 唯一識別,onResult 會回傳它 |
front | ReactNode | — | 正面內容 |
back | ReactNode | — | 背面內容 |
hint | string | — | 正面下方的小提示 |
FlashcardResult
| 欄位 | 型別 | 預設值 | 說明 |
|---|---|---|---|
id | string | — | 字卡 id |
known | boolean | — | true 為「會」、false 為「不會」 |
顏色變數
| 變數 | 預設值 | 說明 |
|---|---|---|
--wb-flashcard-deck-known | #10b981 | 「會」的按鈕、拖曳標籤、統計與圓環顏色 |
--wb-flashcard-deck-unknown | #f43f5e | 「不會」的按鈕、拖曳標籤與統計顏色 |
細節
- 翻面:卡片容器設
perspective: 1200px,內層以 spring 在rotateY0° 與 180° 間切換,正反兩面都是backface-visibility: hidden。 - 堆疊:目前卡下方疊兩張預覽卡(縮放 0.95/0.9、下移 8/16px、透明度 0.7/0.4),分類後下一張從預覽位 spring 浮上來。
- 分類:拖曳時卡片旋轉角度為位移的 1/20,左右兩側浮現「不會」「會」標籤;放開時位移超過 120px 或速度超過 500px/s 就甩出(300ms ease-in,旋轉停在 ±20°),否則彈回中央。
- 撤回時,上一張卡會從當初被甩出的那一側飛回來,重新分類時會再觸發一次
onResult。 - 結束畫面的「只複習不會的」只用本輪
known為false的卡開始新一輪;全部都會時這顆按鈕停用。 shuffle用 seed 驅動的確定性亂數,伺服器與瀏覽器得到同一個順序,不會 hydration 不一致。cards的 id 組合沒變時,即使傳入新陣列也不會重置進度。
可及性
- 卡片容器可聚焦(
tabIndex=0),role="group"、aria-roledescription="字卡",aria-label描述目前位置(例如「第 4 張,共 10 張」) - 鍵盤:空白鍵/Enter 翻面、← 標記不會、→ 標記會、Backspace 或 U 撤回
- 另有可見的「不會」「翻面」「會」按鈕,觸控與輔助科技使用者不必拖曳;翻面按鈕帶
aria-pressed - 未朝上的那一面設
aria-hidden;翻到背面時,背面內容透過aria-live="polite"區域宣告,分類後宣告「已標記為會」或「已標記為不會」 - 進度條為
role="progressbar",附aria-valuenow與aria-valuemax - 使用者系統開啟「減少動態效果」時,翻面改為正反面 200ms 交叉淡接、甩出改為淡出,停用拖曳與所有旋轉,進度條與圓環直接到位