Scroll Timeline
滾動驅動的時間軸,主軸生長線隨捲動延伸,抵達的節點同步亮起並揭示內容。
載入預覽⋯
安裝
npx shadcn@latest add https://webberui.com/r/scroll-timeline.json或在 components.json 設定 registries 後,改用 @webberui/scroll-timeline 安裝。
安裝依賴後,從 registry JSON(/r/scroll-timeline.json 的 files[0].content)複製 scroll-timeline.tsx 原始碼到你的 components/ui/ 目錄:
npm install motion clsx tailwind-merge使用
以 ScrollTimeline 包裹一組 ScrollTimelineItem。捲動時中央主軸的生長線會由上往下延伸,抵達的節點同步亮起。
import { Flag, Rocket } from "lucide-react";
import {
ScrollTimeline,
ScrollTimelineItem,
} from "@/components/ui/scroll-timeline";
<ScrollTimeline>
<ScrollTimelineItem icon={<Flag />} date="2024 · Q1" title="專案啟動">
確立動畫優先的設計原則。
</ScrollTimelineItem>
<ScrollTimelineItem icon={<Rocket />} date="2025 · Q1" title="正式上線">
捲動至此,節點隨生長線一同亮起。
</ScrollTimelineItem>
</ScrollTimeline>;若時間軸放在固定高度的巢狀捲動容器內,將該容器的 ref 傳入 container:
const scrollerRef = React.useRef<HTMLDivElement>(null);
<div ref={scrollerRef} className="h-[300px] overflow-y-auto">
<ScrollTimeline container={scrollerRef}>{/* ... */}</ScrollTimeline>
</div>;Props
ScrollTimeline
| Prop | 型別 | 預設值 | 說明 |
|---|---|---|---|
children | React.ReactNode | — | 放入一組 ScrollTimelineItem |
container | React.RefObject<HTMLElement | null> | — | 巢狀 overflow 捲動容器的 ref;未提供時以視窗為捲動容器 |
activationLine | number | 0.5 | 觸發線在捲動視區中的位置(0=頂端、1=底端),生長線末端與節點點亮皆以此為基準 |
className | string | — | 附加在最外層容器的 class |
ScrollTimelineItem
| Prop | 型別 | 預設值 | 說明 |
|---|---|---|---|
title | React.ReactNode | — | 節點標題 |
date | React.ReactNode | — | 時間或階段標籤,顯示在標題上方 |
icon | React.ReactNode | — | 節點圖示(建議傳入 lucide-react 圖示),點亮後顯示於節點內 |
children | React.ReactNode | — | 節點說明內文 |
className | string | — | 附加在節點 li 上的 class |
細節
- 生長線的末端位置與各節點的點亮時機都以同一條「觸發線」(
activationLine)為基準,因此無論每個節點的高度是否不同,節點永遠在生長線抵達的瞬間亮起,兩者精準同步。 - 主軸末端帶有一顆「彗尾光點」,跟隨生長線前緣移動,強化捲動的方向感。
- 節點與內容會隨捲動進度平滑地由淡轉亮;尚未抵達的節點維持淡色描邊的空心狀態。
可及性
- 使用者系統開啟「減少動態效果」時,直接呈現整條點亮、內容全顯的靜態時間軸,不隨捲動變化。
- 主軸、生長線、節點與光點皆為純裝飾,標記
aria-hidden;時間軸內容以語意化的ol/li結構承載,輔助科技朗讀時為完整清單。 - 巢狀捲動容器範例加上
tabIndex與aria-label,讓鍵盤使用者可聚焦並以方向鍵捲動。