WebberUI

區段指示圓點

固定側邊圓點追蹤當前區段,點擊平滑跳轉,附標籤展開。

以 IntersectionObserver 追蹤各區段的可見比例,當前圓點放大並以流動外環標示、側邊展開標籤,點擊即平滑捲動至該區段,適合長頁面或分段式捲動容器的導覽。

載入預覽⋯

Playground

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

<ScrollSpyDots />

安裝

npx shadcn@latest add https://webberui.com/r/scroll-spy-dots.json

或在 components.json 設定 registries 後,改用 @webberui/scroll-spy-dots 安裝。

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

npm install motion clsx tailwind-merge

使用

import { ScrollSpyDots } from "@/components/ui/scroll-spy-dots";

const sections = [
  { id: "story", label: "品牌故事" },
  { id: "features", label: "核心功能" },
  { id: "contact", label: "聯絡我們" },
];

// 頁面中需存在對應 id 的區段元素
<div className="fixed right-6 top-1/2 -translate-y-1/2">
  <ScrollSpyDots sections={sections} />
</div>

若區段位於自訂捲動容器內,將容器的 ref 傳入 containerRef,觀察與跳轉都會以該容器為捲動根:

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

<div ref={containerRef} className="h-[400px] overflow-y-auto">
  {/* ...含 id 的區段... */}
</div>
<ScrollSpyDots sections={sections} containerRef={containerRef} />

Props

Prop型別預設值說明
sections{ id: string; label: string }[]要追蹤的區段清單,id 對應頁面元素、label 為展開標籤
containerRefReact.RefObject<HTMLElement | null>自訂捲動容器的 ref,未提供時以瀏覽器視窗為捲動根
labelSide"left" | "right""left"標籤展開的方向(相對於圓點)
alwaysShowLabelsbooleanfalse是否讓所有標籤常駐顯示;預設僅當前與 hover/focus 顯示
onActiveChange(id: string) => void當前區段變更時回呼
classNamestring透傳到最外層 nav

可及性

  • nav 地標包裹並標註 aria-label="區段導覽",可被輔助科技快速定位
  • 每個圓點為原生 button,以區段標籤作為 aria-label,當前區段標註 aria-current
  • 支援鍵盤操作:Tab 循序聚焦、Enter/Space 跳轉,聚焦時同步展開標籤並顯示 focus ring
  • 使用者系統開啟「減少動態效果」時,改用即時跳轉(非平滑捲動),外環、放大與標籤動畫皆停用
  • 裝飾用的圓點、外環與軌道線皆標註 aria-hidden,不干擾朗讀

On this page