WebberUI

Alphabet Ledger

字母索引卷軸:海報級巨型首字母作為每個區段的 sticky 錨點,交接時新字母把前一個推出並做字重由細到粗的交棒動畫。

載入預覽⋯

Playground

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

200
800
<AlphabetLedger />

安裝

npx shadcn@latest add https://webberui.com/r/alphabet-ledger.json

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

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

npm install motion clsx tailwind-merge

使用

import {
  AlphabetLedger,
  AlphabetLedgerSection,
} from "@/components/ui/alphabet-ledger";

<AlphabetLedger>
  <AlphabetLedgerSection letter="A" label="Animation">
    <p>內容會在巨型字母旁捲動……</p>
  </AlphabetLedgerSection>
  <AlphabetLedgerSection letter="B" label="Baton">
    <p>捲到這裡時,B 會把 A 推出並補上粗字重。</p>
  </AlphabetLedgerSection>
</AlphabetLedger>

若捲動發生在巢狀 overflow-y-auto 容器內,將該容器的 ref 傳給 container

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

<div ref={scrollerRef} className="h-[320px] overflow-y-auto">
  <AlphabetLedger container={scrollerRef}>{/* ... */}</AlphabetLedger>
</div>

Props

AlphabetLedger

Prop型別預設值說明
childrenReactNode放入 AlphabetLedgerSection,每個為一個字母區段
showIndexbooleantrue是否顯示右側可點擊的字母索引卷軸
thinWeightnumber200非活躍字母的字重(細)
boldWeightnumber800活躍字母的字重(粗),交棒瞬間補到此值
letterSizeClassNamestring"text-[5.5rem] leading-none sm:text-[8rem]"巨型字母的字型級距類名
letterClassNamestring覆寫巨型字母樣式(顏色、字距等)
containerRefObject<HTMLElement | null>巢狀捲動容器 ref,作為釘住偵測與捲動目標
onActiveChange(index: number, letter: string) => void活躍區段變動時回呼
classNamestring附加在外層容器

AlphabetLedgerSection

Prop型別預設值說明
letterstring作為區段錨點的巨型首字母
childrenReactNode區段內容,會在字母旁捲動
labelReactNode字母下方小標,字串型別時同時作為區段的可及性名稱
idstring套用在區段上的錨點 id
classNamestring附加在區段容器

運作細節

  • 每個區段的巨型首字母以 position: sticky; top: 0 釘在頂端,字母的移動被自己的區段邊界所限;當區段捲到底,下一個區段的字母隨即釘住,視覺上把前一個「推出」。
  • 交接瞬間,接手字母的 fontWeightthinWeight 補到 boldWeight(配合微幅縮放),前一個同時退回細字重,形成「交棒」動畫。字重過渡的平滑度取決於字型是否為可變字重字型(variable font)。
  • 活躍區段由 IntersectionObserver 判定:以最深層已越過頂端釘住線的區段為活躍者,右側索引卷軸與字重同步更新。
  • 傳入 container 時,釘住偵測(IntersectionObserver root)與索引卷軸的捲動定位都會改用該容器;不傳則以視窗為捲動容器。

可及性

  • 巨型字母為裝飾性視覺錨點,標記 aria-hidden;請在區段內容中提供實際標題,label 為字串時會作為 <section>aria-label
  • 右側索引卷軸為原生 <button>,可鍵盤聚焦、Enter 觸發,並帶有 aria-labelaria-current 標記當前區段。
  • 使用者系統開啟「減少動態效果」時,sticky 堆疊版面完整保留,僅停用字重交棒過渡與平滑捲動(改為即時跳位)。

On this page