Chaptered Report Shell
年報/白皮書式頁面骨架:sticky 章節導軌自內容自動生成、巨型章節數字跨章交叉淡出、章與章以全幅色塊過場,並附雙重閱讀進度標記。
載入預覽⋯
Playground
即時調整 props、程式碼片段同步更新——直接試出你要的樣子再複製。
16
<ChapteredReportShell />
安裝
npx shadcn@latest add https://webberui.com/r/chaptered-report-shell.json安裝依賴後,從 registry JSON(/r/chaptered-report-shell.json 的 files[0].content)複製 chaptered-report-shell.tsx 原始碼到你的 components/ui/ 目錄:
npm install motion clsx tailwind-merge使用
直接放入 ReportChapter 子元件,左側章節導軌會自其 id/title/number 自動生成,
章節編號未指定時依順序自動編為兩位數:
import {
ChapteredReportShell,
ReportChapter,
} from "@/components/ui/chaptered-report-shell";
<ChapteredReportShell eyebrow="2025 年度報告">
<ReportChapter id="overview" title="全年概覽" kicker="Overview">
<p>第一章內文……</p>
</ReportChapter>
<ReportChapter
id="financials"
title="財務表現"
kicker="Financials"
accentClassName="bg-indigo-600 dark:bg-indigo-500"
>
<p>第二章內文……</p>
</ReportChapter>
<ReportChapter
id="outlook"
title="未來展望"
accentClassName="bg-amber-500"
>
<p>第三章內文……</p>
</ReportChapter>
</ChapteredReportShell>捲動發生在巢狀 overflow 容器內時,把該容器的 ref 傳給 container(進度標記與過場動畫皆會以它為準):
const scrollerRef = React.useRef<HTMLDivElement>(null);
<div ref={scrollerRef} className="h-[400px] overflow-y-auto">
<ChapteredReportShell container={scrollerRef} stickyTop={8}>
{/* ... */}
</ChapteredReportShell>
</div>Props
ChapteredReportShell
| Prop | 型別 | 預設值 | 說明 |
|---|---|---|---|
children | ReactNode | — | 直接放入 ReportChapter 子元件,導軌自其 props 生成 |
container | RefObject<HTMLElement> | — | 捲動發生在巢狀 overflow 容器內時,傳入該容器的 ref |
eyebrow | ReactNode | — | 導軌上方的小標,如「2025 年度報告」 |
label | string | "章節導覽" | 導軌 <nav> 的無障礙標籤 |
stickyTop | number | 16 | sticky 導軌與進度條距頂端的偏移(px),巢狀捲動時可設 0 |
className | string | — | 附加到最外層容器的 class |
ReportChapter
| Prop | 型別 | 預設值 | 說明 |
|---|---|---|---|
id | string | — | 章節錨點 id,導軌點擊與觀察器以此對應 |
title | string | — | 章節標題,顯示於導軌與過場色塊 |
number | string | 依序自動編號 | 章節編號字串,未提供時自動編為兩位數(01、02…) |
kicker | ReactNode | — | 過場色塊左上的分類小標 |
accentClassName | string | 中性深底 | 過場色塊底色的 Tailwind class,需為可承白字的實色,如 "bg-indigo-600" |
children | ReactNode | — | 章節內文 |
className | string | — | 附加到章節 <section> 的 class |
細節
- 章節導軌完全由
ReportChapter的 props 自動生成:無需另外維護一份目錄清單,新增章節即自動出現在導軌 - 當前章節以
IntersectionObserver(root為捲動容器)取各章可見比例、最高者為準,切換不跳格 - 巨型章節數字以
AnimatePresence跨章交叉淡出:舊數字上移淡出、新數字自下浮入並解除模糊 - 每章開頭為全幅過場色塊,進入視口時自左擦入(
scaleX),數字與標題再延後浮出 - 雙重閱讀進度標記:頂部進度條連動
scrollYProgress,導軌軌道上另有沿途滑動的閱讀游標與逐章點亮的標記點 - 導軌項是真正的
<button>,點擊平滑捲動到對應章節,並以aria-current="location"標示當前位置;當前章節同時以字重與顏色標示,不只依賴色點 - 視窗較窄時導軌自動收合(以
@container判斷容器寬度),內容欄不受影響 - 使用者系統開啟「減少動態效果」時:色塊直接呈現、數字即時切換、進度連動不經彈簧平滑、點擊導軌改為即時捲動,版面與內容完全不變