WebberUI

Paginated Wave Grid

帶分頁器的網格版面:換頁時出場項目朝翻頁方向依距離波次退場,新頁項目自反方向湧入補位,頁碼與總數同步滾動變形。

載入預覽⋯

Playground

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

3
6
40
0.05
0.5
<PaginatedWaveGrid />

安裝

npx shadcn@latest add https://webberui.com/r/paginated-wave-grid.json

或在 components.json 設定 registries 後,改用 @webberui/paginated-wave-grid 安裝。

安裝依賴後,從 registry JSON(/r/paginated-wave-grid.jsonfiles[0].content)複製 paginated-wave-grid.tsx 原始碼到你的 components/ui/ 目錄:

npm install motion lucide-react clsx tailwind-merge

使用

import { PaginatedWaveGrid } from "@/components/ui/paginated-wave-grid";

const items = Array.from({ length: 18 }, (_, i) => ({ id: i, label: `#${i}` }));

<PaginatedWaveGrid
  items={items}
  pageSize={6}
  columns={3}
  getItemKey={(item) => item.id}
  renderItem={(item) => (
    <div className="flex h-24 items-center justify-center rounded-xl border">
      {item.label}
    </div>
  )}
/>;

換頁方向由前後頁碼自動判斷:往後翻時,舊頁項目依「與左緣的距離」分波次向左退場,新頁項目自右側湧入補位;往前翻則整組方向相反。底部頁碼與總數以里程表方式逐位滾動到新值。

受控模式

傳入 pageonPageChange 即進入受控模式,可與外部狀態或其他控制元件同步:

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

<PaginatedWaveGrid page={page} onPageChange={setPage} items={items} renderItem={/* … */} />;

Props

Prop型別預設值說明
itemsT[]資料陣列,依 pageSize 切成多頁
renderItem(item: T, index: number) => ReactNode單一項目的渲染函式
pageSizenumber6每頁項目數
columnsnumber3網格欄數
gapnumber12網格間距(px)
travelnumber40波次進出場的水平位移距離(px)
waveStaggernumber0.05每一距離階之間的延遲(秒),決定波紋速度
rowWeightnumber0.5列方向對波次階數的加權,>0 形成對角波紋
durationnumber0.5單一項目進出場時長(秒)
blurbooleantrue進出場是否附帶模糊
loopbooleanfalse首尾相接循環翻頁
pagenumber受控目前頁碼(1 起算)
defaultPagenumber1非受控模式的初始頁碼
onPageChange(page: number) => void頁碼變更回呼
showControlsbooleantrue是否顯示內建翻頁控制列
getItemKey(item: T, index: number) => Key為每個項目產生穩定 key
aria-labelstring"分頁波次網格"無障礙標籤
classNamestring套用在最外層容器
gridClassNamestring套用在網格容器
itemClassNamestring套用在每個項目外層

細節

  • 出場層以絕對定位疊在新頁之上(pointer-events-none),因此新頁能立即回填版位,舊項目在其上方飛離淡出。
  • 每個版位的波次階數 = 前緣欄距 + 列距 × rowWeight,出場與湧入共用同一階數,形成連貫的掃掠。
  • 頁碼採里程表式的直向膠捲,各位數獨立滾動到目標數字;位數增減時以「右起位數」為 key,保持各欄對齊。
  • 過場計時以 rAF 無關的 setTimeout 收尾,於卸載與下次換頁時清除。

可及性

  • 內建 上一頁 / 下一頁 按鈕具備 aria-label、鍵盤聚焦樣式,並在抵達首/末頁時停用(loop 開啟時不停用)。
  • 容器聚焦時支援 / 方向鍵翻頁。
  • aria-live="polite" 的隱藏區域,換頁時朗讀「第 X 頁,共 Y 頁」。
  • 里程表數字對輔助科技隱藏(aria-hidden),避免逐位數字造成噪音。
  • 使用者系統開啟「減少動態效果」時,停用波次位移、模糊與滾動,換頁直接切換版面。

On this page