導航

滑動分頁

當前頁底塊在頁碼間滑動的 React 分頁元件:省略號可點開中間頁碼並錯開淡入,另有只顯示「3 / 12」且數字逐位滾動的精簡變體,支援鍵盤左右換頁與 SEO 友善的連結模式。

列表、搜尋結果、商品頁都用得到的分頁器。當前頁的深色底塊會以彈簧動畫在頁碼之間滑動,頁碼文字隨之反白;頁數多時首尾固定顯示、當前頁左右保留幾頁,其餘收進「…」——點一下省略號,被藏起來的頁碼會逐一錯開淡入。空間有限時改用 compact 精簡變體,只顯示「3 / 12」,翻頁時數字逐位上滾或下滾。頁碼支援受控/非受控雙模式;提供 getHref 時每一頁都渲染成真正的連結,搜尋引擎抓得到。

把這個效果裝進你的專案

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

npx webberui@latest add pagination

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

Playground

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

24
1
200
500
編輯中的呼叫預設屬性
<Pagination/>

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

安裝

npx webberui@latest add https://webberui.com/r/pagination.json

或在 components.json 設定 registries 後,改用 @webberui/pagination 安裝。

使用

import { Pagination } from "@/components/ui/pagination";

const [page, setPage] = React.useState(1);

<Pagination page={page} onPageChange={setPage} total={24} />

// 精簡變體:只顯示「3 / 12」
<Pagination compact page={page} onPageChange={setPage} total={12} />

// 連結模式:每一頁都是 <a href>,讓搜尋引擎能抓到
<Pagination
  defaultPage={1}
  total={24}
  getHref={(p) => `/products?page=${p}`}
/>

Props

Prop型別預設值說明
pagenumber—受控的當前頁(1-based);未提供時由元件內部管理(非受控)
defaultPagenumber1非受控模式的初始頁(1-based)
onPageChange(page: number) => void—切換頁碼時回呼,參數為新的頁碼
totalnumber—總頁數(必填)
siblingCountnumber1當前頁左右各顯示幾個頁碼
boundaryCountnumber1首尾各固定顯示幾個頁碼
compactbooleanfalse精簡變體:只顯示「3 / 12」與上一頁、下一頁,數字逐位滾動
showFirstLastbooleanfalse顯示跳到第一頁/最後一頁的 «、» 按鈕
prevLabelstring"上一頁"上一頁按鈕文字(手機寬度只留圖示,文字改為 aria-label)
nextLabelstring"下一頁"下一頁按鈕文字(手機寬度只留圖示,文字改為 aria-label)
getHref(page: number) => string—提供時每個頁碼渲染成 <a href>;否則渲染成按鈕
durationnumber200淡入與 hover 過渡時間(毫秒),同時寫入 --wb-pagination-duration
staggernumber30展開省略號時,頁碼逐一淡入的間隔(毫秒)
stiffnessnumber500當前頁底塊與數字滾動的彈簧剛性
dampingnumber35當前頁底塊與數字滾動的彈簧阻尼
aria-labelstring"分頁"nav 的無障礙名稱
classNamestring—透傳到最外層 nav

另外具名匯出純函式 getRange(page, total, siblingCount, boundaryCount),回傳 (number | "ellipsis-left" | "ellipsis-right")[],方便在伺服器端或自訂樣式時沿用同一套頁碼演算法。

細節

  • 頁碼演算法:首尾各固定 boundaryCount 頁、當前頁左右各 siblingCount 頁;總頁數少於 boundaryCount × 2 + siblingCount × 2 + 3 時全部顯示。當前頁靠近首尾時兄弟頁視窗會往內推,頁碼列的項目數維持固定、不會忽長忽短;省略號只在至少藏兩頁時出現。
  • 當前頁底塊是一個共用 layoutId 的元素,換頁時以彈簧(stiffness/damping)滑到新位置;頁碼列增減時其他項目以 layout 動畫重新排位,新出現的頁碼淡入並輕微放大。
  • 點「…」會用它所代表的頁碼取代它,從最靠近當前頁的那一頁開始以 stagger 間隔逐一淡入;隱藏頁超過 10 頁時只展開最近的 10 頁並保留剩下的省略號,可再點一次繼續展開。換頁後展開狀態重置。
  • 精簡變體的每一位數字是獨立的滾動欄,只有改變的那一位會動;往後翻頁時新數字由下往上滾入,往前翻則由上往下。
  • 提供 getHref 時頁碼是一般連結:點擊會照常導覽,同時呼叫 onPageChange。用框架路由時,可在 onPageChange 裡自行處理。
  • 時間變數:根元素寫入 --wb-pagination-duration(預設 200ms),hover 背景過渡使用它,可在全域樣式覆寫。

可及性

  • 最外層是 <nav>,以 aria-label(預設「分頁」)命名;當前頁設定 aria-current="page",每個頁碼的 aria-label 為「第 N 頁」
  • 省略號是按鈕,aria-label 說明會展開哪幾頁(例如「顯示第 4 到 9 頁」)
  • 第一頁時「上一頁」、最後一頁時「下一頁」設定 aria-disabled 而非 disabled,按鈕仍可聚焦,螢幕閱讀器會告知已停用
  • 焦點在任一分頁按鈕時,← / → 切換上一頁/下一頁,Home/End 跳到首尾頁,焦點會跟著移到新的當前頁
  • 精簡變體以視覺隱藏、aria-live="polite" 的文字朗讀「第 3 頁,共 12 頁」,滾動中的數字對輔助科技隱藏
  • 使用者系統開啟「減少動態效果」時,底塊直接跳到新位置、展開不錯開、精簡變體的數字直接替換