MenuClose

Block Milestones — React Page Block

Milestone progress: a roadmap strip whose completed steps light up in sequence on scroll-in, the current step breathes, and upcoming steps stay dimmed. Which steps are done is pure data.

View source
PreviewReact
Starting live preview

Usage

import { BlockMilestones } from "@/components/BlockMilestones";

export function Roadmap() {
  return (
    <BlockMilestones
      title="Where we are in the plan."
      milestones={[
        { name: "Whiteboard", note: "The first graph." },
        { name: "Replays", note: "Scrub the week." },
        { name: "Self-hosted", note: "In progress.", current: true },
      ]}
      current={2}
      {...{
        title: "Where we are in the plan.",
        current: 0,
        accent: "#d5ed9a",
        scheme: "dark"
      }}
    />
  );
}
Implementation notes & API

Purpose: roadmap/milestone progress strip. Copy it, ship it — every string, link and color arrives through props. Runtime: pure DOM + CSS. No WebGPU, canvas, animation library or external assets; SSR-safe on first render. Theming: root custom properties (--vb-bg, --vb-fg, --vb-accent, --vb-border, --vb-radius, --vb-container) or the accent/scheme/className/style props. scheme flips the dark default to light. Guardrails: responsive via container queries down to 320px; interactive behavior degrades on touch; prefers-reduced-motion drops entrance/scroll motion while content stays complete. The aria-label is "Milestone progress"; a vertical version renders on narrow screens. Reduced motion shows the settled strip.

PropertyTypeNotes / default
eyebrow / title / descriptionReactNodeSection header
milestonesreadonly Milestone[]{ name, note?, current? }
currentnumberIndex in progress; steps before it count as done
demoNoteReactNode | nullFictional-roadmap marker; pass null with your plan
scheme"dark" | "light"dark
accentstring (hex)Sets --vb-accent for the whole block
className / stylestring / CSSPropertiesApplied to the section root
childrenReactNodeReplaces the default content entirely
View source on GitHubFree for commercial projects · MIT