WebberUI

Running Head Folio

書籍書眉系統:sticky 細列左側顯示當前章名、右側顯示依捲動位置換算的頁碼,跨章時章名翻頁式翻轉、頁碼連動遞增。

載入預覽⋯

Playground

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

1
40
300
<RunningHeadFolio />

安裝

npx shadcn@latest add https://webberui.com/r/running-head-folio.json

或在 components.json 設定 registries 後,改用 @webberui/running-head-folio 安裝。

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

npm install motion clsx tailwind-merge

使用

RunningHeadFolio 包住若干 RunningHeadFolioChapter,每個章節的 title 會成為書眉列上的章名。若閱讀區是巢狀捲動容器,把容器 ref 傳給 container

import {
  RunningHeadFolio,
  RunningHeadFolioChapter,
} from "@/components/ui/running-head-folio";

export function Reader() {
  const scrollerRef = React.useRef<HTMLDivElement>(null);

  return (
    <div ref={scrollerRef} className="h-[70vh] overflow-y-auto">
      <RunningHeadFolio container={scrollerRef} center="progress" startPage={1}>
        <RunningHeadFolioChapter title="序章">
          {/* 章節內容 */}
        </RunningHeadFolioChapter>
        <RunningHeadFolioChapter title="第一章">
          {/* 章節內容 */}
        </RunningHeadFolioChapter>
      </RunningHeadFolio>
    </div>
  );
}

center 可切換中央欄位:"progress" 顯示閱讀進度細線、"title" 顯示 bookTitle"none" 留白。頁碼呈現可用 format 客製,例如羅馬數字:

<RunningHeadFolio
  container={scrollerRef}
  center="title"
  bookTitle="動態排版手記"
  format={(p) => `p. ${p}`}
>
  {/* … */}
</RunningHeadFolio>

Props

RunningHeadFolio

Prop型別預設值說明
childrenReactNode放入 RunningHeadFolioChapter 子元件
containerRefObject<HTMLElement | null>巢狀捲動容器 ref;預設以視窗為捲動容器
center"title" | "progress" | "none""progress"中央欄位樣式
bookTitleReactNode中央書名(center="title" 時使用)
startPagenumber1起始頁碼
pageHeightnumber容器一個畫面高每頁對應的捲動距離(px)
barHeightnumber40書眉列高度(px)
format(page: number) => ReactNode(p) => p自訂頁碼呈現
classNamestring外層容器 class
barClassNamestring書眉列 class(可覆寫底色)

RunningHeadFolioChapter

Prop型別預設值說明
titleReactNode章節名稱,顯示於書眉列
childrenReactNode章節內容
idstring章節容器的錨點 id
classNamestring章節容器 class

細節

  • 頁碼換算:以 useScroll 的捲動進度對映 [startPage, startPage + 總頁數 − 1];總頁數由內容總高除以 pageHeight 求得,pageHeight 未指定時取捲動容器一個畫面高,讓「一個畫面約等於一頁」。
  • 當前章判定:以書眉列下緣為基準線,取最後一個頂端已越過基準線的章節為當前章,因此章名切換的時機與閱讀位置一致。
  • 翻頁方向:翻轉方向會辨識捲動去向——向下遞增時新值自下翻入,向上回溯時反向翻落。
  • 自適應:以 ResizeObserver 監看內容與容器尺寸,尺寸變動時重算總頁數與當前章。

可及性

  • 書眉列標記 role="status" 並帶 aria-label,內含純文字摘要(第幾章、第幾頁)供輔助科技朗讀;翻頁的視覺重複內容標記 aria-hidden,不會重複朗讀。
  • 每個章節為原生 section,字串 title 會作為其 aria-label
  • 開啟系統「減少動態效果」時,翻頁動畫改為極短的淡入淡出,其餘資訊與版面完全保留。

On this page