WebberUI

Section Snap Pin

區段釘選 + 吸附滾動編排:全高區段逐一吸附填滿視口,內容依序進場與退場,並附側邊導覽點。

載入預覽⋯

Playground

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

<SectionSnapPin />

安裝

npx shadcn@latest add https://webberui.com/r/section-snap-pin.json

或在 components.json 設定 registries 後,改用 @webberui/section-snap-pin 安裝。

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

npm install motion clsx tailwind-merge

使用

SectionSnapPin 本身即為一個垂直吸附捲動容器,請為它設定固定高度(例如 h-[80vh]h-screen)。內部放入多個 SnapSection,每個區段再以 SnapReveal 包住要編排進場的元素。

import {
  SectionSnapPin,
  SnapSection,
  SnapReveal,
} from "@/components/ui/section-snap-pin";

<SectionSnapPin className="h-screen">
  <SnapSection label="概覽" className="bg-neutral-950 text-white">
    <SnapReveal order={0}>
      <span className="text-xs tracking-widest uppercase">01</span>
    </SnapReveal>
    <SnapReveal order={1}>
      <h2 className="text-4xl font-semibold">吸附式區段</h2>
    </SnapReveal>
  </SnapSection>

  <SnapSection label="編排" className="bg-indigo-600 text-white">
    <SnapReveal order={0} from="left">
      <h2 className="text-4xl font-semibold">依序進場</h2>
    </SnapReveal>
  </SnapSection>
</SectionSnapPin>

Props

SectionSnapPin

Prop型別預設值說明
childrenReactNode一個或多個 SnapSection
snap"mandatory" | "proximity""mandatory"吸附強度
indicatorbooleantrue是否顯示側邊區段導覽點
indicatorPosition"left" | "right""right"導覽點位置
onActiveChange(index: number) => void吸附區段切換時回呼
aria-labelstring"區段吸附捲動"捲動區的無障礙標籤
classNamestring最外層容器(設定固定高度)

SnapSection

Prop型別預設值說明
childrenReactNode區段內容,通常放入數個 SnapReveal
labelstring區段名稱:作為導覽點提示與無障礙標籤
align"start" | "center" | "end""center"內容在區段內的垂直對齊
classNamestring附加樣式(背景、文字色等)

SnapReveal

Prop型別預設值說明
childrenReactNode要編排進場的內容
ordernumber0進場順序,乘上 stagger 得延遲
from"up" | "down" | "left" | "right" | "none""up"進場位移方向
distancenumber24進場位移距離(px)
staggernumber0.08每階順序的間隔(秒)
durationnumber0.6單一單位動畫時長(秒)
classNamestring附加樣式

細節

  • SectionSnapPin 使用 CSS Scroll Snap(snap-y + snap-mandatorysnap-proximity)達成吸附,捲動效能交給瀏覽器原生處理。
  • 每個 SnapSectionIntersectionObserver(root 為捲動容器)判斷自己是否超過 55% 可見,成為主要區段;此狀態透過 context 傳給內部 SnapReveal 觸發進場,離開時退場,因此重新捲入會再次編排。
  • 側邊導覽點旁的細軌以 useScroll 追蹤容器捲動進度即時填充。
  • 捲動容器的原生捲軸以樣式隱藏,改由吸附與導覽點提供位置感。

可及性

  • 捲動容器帶 role="region"aria-labeltabIndex,可用鍵盤聚焦後以 PageUpPageDownHomeEnd 切換區段。
  • 導覽點為原生 <button>,帶 aria-label(採用區段 label)與 aria-current,可鍵盤操作並顯示提示。
  • 使用者系統開啟「減少動態效果」時,平滑捲動改為即時跳轉,SnapReveal 直接渲染靜態內容、不做進場位移。

On this page