區段指示圓點
固定側邊圓點追蹤當前區段,點擊平滑跳轉,附標籤展開。
以 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.json 的 files[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 為展開標籤 |
containerRef | React.RefObject<HTMLElement | null> | — | 自訂捲動容器的 ref,未提供時以瀏覽器視窗為捲動根 |
labelSide | "left" | "right" | "left" | 標籤展開的方向(相對於圓點) |
alwaysShowLabels | boolean | false | 是否讓所有標籤常駐顯示;預設僅當前與 hover/focus 顯示 |
onActiveChange | (id: string) => void | — | 當前區段變更時回呼 |
className | string | — | 透傳到最外層 nav |
可及性
- 以
nav地標包裹並標註aria-label="區段導覽",可被輔助科技快速定位 - 每個圓點為原生
button,以區段標籤作為aria-label,當前區段標註aria-current - 支援鍵盤操作:Tab 循序聚焦、Enter/Space 跳轉,聚焦時同步展開標籤並顯示 focus ring
- 使用者系統開啟「減少動態效果」時,改用即時跳轉(非平滑捲動),外環、放大與標籤動畫皆停用
- 裝飾用的圓點、外環與軌道線皆標註
aria-hidden,不干擾朗讀