Orbit Timeline
Events arranged around concentric orbits, expanding a detail card when one is selected.
Years become concentric orbits (increasing from the inside out), with event nodes distributed along the arcs and slowly revolving, the outer rings turning more slowly with distance. Clicking a node stops the whole system and pops a detail card in the center — well suited to narrating a brand's or a product's history through a solar-system metaphor.
Loading preview…
npx shadcn@latest add https://webberui.com/r/orbit-timeline.jsonPlayground
Tune the props live — the code snippet updates as you go, so you can dial in the look you want before copying it.
40
<OrbitTimeline />
Installation
npx shadcn@latest add https://webberui.com/r/orbit-timeline.jsonOr, once registries are configured in components.json, install it as @webberui/orbit-timeline.
Usage
import { OrbitTimeline } from "@/components/ui/orbit-timeline";
<OrbitTimeline
events={[
{ year: 2022, title: "Seed round", detail: "Round closed, and the team grew to eight." },
{ year: 2023, title: "Public launch", detail: "Topped the dev community charts in the first week." },
{ year: 2024, title: "Component library open-sourced", detail: "The core motion component library went open source." },
]}
/>Props
| Prop | Type | Default | Description |
|---|---|---|---|
events | OrbitTimelineEvent[] | — | The list of events, grouped into concentric orbits by year |
period | number | 40 | Seconds for one revolution of the innermost orbit; outer orbits slow down ring by ring with distance |
autoRotate | boolean | true | Whether revolution starts automatically after mount |
hint | string | "點擊節點查看詳情" | Hint text shown in the center while no event is selected — the built-in default is Traditional Chinese for "click a node to see details", so pass this prop to localize it |
className | string | — | Forwarded to the outer container |
OrbitTimelineEvent fields:
| Field | Type | Description |
|---|---|---|
year | number | The event year; events sharing a year land on the same orbit |
title | string | Event title, shown both on hover and in the detail card |
detail | string | The description text the detail card expands to show |
hue | number? | Node hue 0–360; colored automatically by orbit when omitted |
Accessibility
- When the user has "reduce motion" enabled at the system level, the revolution stops and the play button is hidden, the nodes present at static positions, and clicking to expand the details is unaffected
- Every node is
role="button", Tab focusable, opens and closes its details with Enter or Space, and marks its selected state witharia-pressed - Each node's
aria-labelincludes the year and the title (such as "2023: Public launch"), and the detail card's close button has an explicitaria-label - The rAF animation loop pauses automatically once the component leaves the visible area, saving on performance