滾動敘事

Data Duel Split

頁面級 A/B 對決分屏,逐回合捲動揭示指標,中央分界線像拔河般滑移、底部累計比分同步跳動。

這是 WebberUI Pro 元件

下方的安裝指令需要授權才能執行,未授權時會回 401。

怎麼安裝 Pro 元件 →查看方案 →

把這個效果裝進你的專案

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

npx webberui@latest add "https://webberui.com/r/data-duel-split.json?t=<安裝 token>"

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

Playground

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

300
編輯中的呼叫預設屬性
<DataDuelSplit/>

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

安裝

npx webberui@latest add "https://webberui.com/r/data-duel-split.json?t=<安裝 token>"

或在 components.json 設定 registries 後,改用 @webberui/data-duel-split 安裝。

使用

import { DataDuelSplit } from "@/components/ui/data-duel-split";

<DataDuelSplit
  left={{ name: "Nova" }}
  right={{ name: "Atlas" }}
  rounds={[
    { label: "首屏載入", left: 420, right: 680, suffix: "ms", win: "lower" },
    { label: "轉換率", left: 3.1, right: 4.6, suffix: "%", format: (v) => v.toFixed(1) },
    { label: "月活躍用戶", left: 128, right: 96, suffix: "k" },
  ]}
/>

預設以整個視窗為捲動容器、舞台高度為 100vh,直接放進頁面即可成為一段捲動敘事。若要嵌在某個 overflow-y-auto 區塊裡,將該區塊的 ref 傳給 container,並把 stageHeight 設成固定像素:

const scrollerRef = React.useRef<HTMLDivElement>(null);

<div ref={scrollerRef} className="h-[300px] overflow-y-auto">
  <DataDuelSplit container={scrollerRef} stageHeight="300px" left={/* … */} right={/* … */} rounds={/* … */} />
</div>

Props

DataDuelSplit

Prop型別預設值說明
leftDuelTeam—左方陣營設定
rightDuelTeam—右方陣營設定
roundsDuelRound[]—逐回合對決資料,依捲動順序揭示
stageHeightstring"100vh"舞台高度(CSS 長度);巢狀容器內建議傳固定像素
containerRefObject<HTMLElement | null>—巢狀 overflow 捲動容器的 ref;預設以視窗為捲動容器
classNamestring—附加在最外層容器的 class

DuelTeam

欄位型別預設值說明
namestring—陣營名稱
accentstring左 #4f46e5/右 #e11d48強調色(任意 CSS 顏色),用於填充、比分與勝方數值
iconReact.ReactNode—顯示在名稱旁的小圖示或標誌

DuelRound

欄位型別預設值說明
labelstring—該回合對比的指標名稱
leftnumber—左方數值
rightnumber—右方數值
format(value: number) => stringtoLocaleString數值格式化函式
suffixstring—數值後綴,例如 "%"、"ms"、"k"
noteReact.ReactNode—該回合的補充說明
win"higher" | "lower""higher"勝負判定:數值高者勝或低者勝

細節

  • 拔河分界線:以 useScroll 取得捲動進度,在各回合的優勢佔比之間連續插值,再套一層 useSpring 讓分界線帶點慣性,像被兩側拉扯的繩子。優勢佔比夾在 12%–88% 之間,確保兩側標籤永遠可見。
  • 累計比分:比分只計入「目前回合(含)之前」的勝負,回合切換時分數以 spring 彈跳呈現「跳動」感。win: "lower" 的回合以數值較低者為勝方。
  • 回合值揭示:每回合的指標數字在進場時由 0 spring 到目標值;整數維持整數、含小數則保留小數。
  • 巢狀捲動:容器最外層高度為 stageHeight × 回合數,內部舞台以 sticky top-0 釘住。透過 container 支援在任意 overflow-y-auto 區塊內捲動。

可及性

  • 使用者系統開啟「減少動態效果」時,改以靜態的逐列對比長條與最終比分呈現,不再依賴捲動與動畫。
  • 視覺舞台對輔助科技隱藏(aria-hidden),另提供一份 sr-only 的完整摘要清單,逐回合朗讀雙方數值與勝方。
  • 最外層以 role="group" 搭配 aria-label 標記整段對決,方便輔助科技辨識區塊用途。